1 /* BFD back-end for oasys objects. 2 Copyright (C) 1990-2014 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 if (bfd_seek (abfd, filepos, SEEK_SET) != 0) 276 return NULL; 277 278 /* There are two ways of specifying the archive header. */ 279 { 280 oasys_extmodule_table_type_b_type record_ext; 281 282 amt = sizeof (record_ext); 283 if (bfd_bread ((void *) &record_ext, amt, abfd) != amt) 284 return NULL; 285 286 record.mod_size = H_GET_32 (abfd, record_ext.mod_size); 287 record.file_offset = H_GET_32 (abfd, record_ext.file_offset); 288 289 record.dep_count = H_GET_32 (abfd, record_ext.dep_count); 290 record.depee_count = H_GET_32 (abfd, record_ext.depee_count); 291 record.sect_count = H_GET_32 (abfd, record_ext.sect_count); 292 record.module_name_size = H_GET_32 (abfd, 293 record_ext.mod_name_length); 294 295 amt = record.module_name_size; 296 module[i].name = bfd_alloc (abfd, amt + 1); 297 if (!module[i].name) 298 return NULL; 299 if (bfd_bread ((void *) module[i].name, amt, abfd) != amt) 300 return NULL; 301 module[i].name[record.module_name_size] = 0; 302 filepos += (sizeof (record_ext) 303 + record.dep_count * 4 304 + record.module_name_size + 1); 305 } 306 307 module[i].size = record.mod_size; 308 module[i].pos = record.file_offset; 309 module[i].abfd = 0; 310 } 311 } 312 return abfd->xvec; 313 } 314 315 static bfd_boolean 316 oasys_mkobject (bfd *abfd) 317 { 318 bfd_size_type amt = sizeof (oasys_data_type); 319 320 abfd->tdata.oasys_obj_data = bfd_alloc (abfd, amt); 321 322 return abfd->tdata.oasys_obj_data != NULL; 323 } 324 325 /* The howto table is build using the top two bits of a reloc byte to 326 index into it. The bits are PCREL,WORD/LONG. */ 327 328 static reloc_howto_type howto_table[] = 329 { 330 331 HOWTO (0, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), 332 HOWTO (0, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs32", TRUE, 0xffffffff, 0xffffffff, FALSE), 333 HOWTO (0, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), 334 HOWTO (0, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "pcrel32", TRUE, 0xffffffff, 0xffffffff, FALSE) 335 }; 336 337 /* Read in all the section data and relocation stuff too. */ 338 339 static bfd_boolean 340 oasys_slurp_section_data (bfd *const abfd) 341 { 342 oasys_record_union_type record; 343 oasys_data_type *data = OASYS_DATA (abfd); 344 bfd_boolean loop = TRUE; 345 oasys_per_section_type *per; 346 asection *s; 347 bfd_size_type amt; 348 349 /* See if the data has been slurped already. */ 350 for (s = abfd->sections; s != NULL; s = s->next) 351 { 352 per = oasys_per_section (s); 353 if (per->initialized) 354 return TRUE; 355 } 356 357 if (data->first_data_record == 0) 358 return TRUE; 359 360 if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0) 361 return FALSE; 362 363 while (loop) 364 { 365 if (! oasys_read_record (abfd, &record)) 366 return FALSE; 367 368 switch (record.header.type) 369 { 370 case oasys_record_is_header_enum: 371 break; 372 case oasys_record_is_data_enum: 373 { 374 bfd_byte *src = record.data.data; 375 bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length; 376 bfd_byte *dst_ptr; 377 bfd_byte *dst_base_ptr; 378 unsigned int relbit; 379 unsigned int count; 380 asection *section = 381 data->sections[record.data.relb & RELOCATION_SECT_BITS]; 382 bfd_vma dst_offset; 383 384 per = oasys_per_section (section); 385 386 if (! per->initialized) 387 { 388 arelent **relpp; 389 390 per->data = bfd_zalloc (abfd, section->size); 391 if (!per->data) 392 return FALSE; 393 relpp = §ion->relocation; 394 per->reloc_tail_ptr = (oasys_reloc_type **) relpp; 395 per->had_vma = FALSE; 396 per->initialized = TRUE; 397 section->reloc_count = 0; 398 section->flags = SEC_ALLOC; 399 } 400 401 dst_offset = H_GET_32 (abfd, record.data.addr); 402 if (! per->had_vma) 403 { 404 /* Take the first vma we see as the base. */ 405 section->vma = dst_offset; 406 per->had_vma = TRUE; 407 } 408 409 dst_offset -= section->vma; 410 411 dst_base_ptr = oasys_per_section (section)->data; 412 dst_ptr = oasys_per_section (section)->data + 413 dst_offset; 414 415 if (src < end_src) 416 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS; 417 418 while (src < end_src) 419 { 420 unsigned char mod_byte = *src++; 421 size_t gap = end_src - src; 422 423 count = 8; 424 if (mod_byte == 0 && gap >= 8) 425 { 426 dst_ptr[0] = src[0]; 427 dst_ptr[1] = src[1]; 428 dst_ptr[2] = src[2]; 429 dst_ptr[3] = src[3]; 430 dst_ptr[4] = src[4]; 431 dst_ptr[5] = src[5]; 432 dst_ptr[6] = src[6]; 433 dst_ptr[7] = src[7]; 434 dst_ptr += 8; 435 src += 8; 436 } 437 else 438 { 439 for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1) 440 { 441 if (relbit & mod_byte) 442 { 443 unsigned char reloc = *src; 444 /* This item needs to be relocated. */ 445 switch (reloc & RELOCATION_TYPE_BITS) 446 { 447 case RELOCATION_TYPE_ABS: 448 break; 449 450 case RELOCATION_TYPE_REL: 451 { 452 /* Relocate the item relative to the section. */ 453 oasys_reloc_type *r; 454 455 amt = sizeof (oasys_reloc_type); 456 r = bfd_alloc (abfd, amt); 457 if (!r) 458 return FALSE; 459 *(per->reloc_tail_ptr) = r; 460 per->reloc_tail_ptr = &r->next; 461 r->next = NULL; 462 /* Reference to undefined symbol. */ 463 src++; 464 /* There is no symbol. */ 465 r->symbol = 0; 466 /* Work out the howto. */ 467 abort (); 468 r->relent.address = dst_ptr - dst_base_ptr; 469 r->relent.howto = &howto_table[reloc >> 6]; 470 r->relent.sym_ptr_ptr = NULL; 471 section->reloc_count++; 472 473 /* Fake up the data to look like 474 it's got the -ve pc in it, this 475 makes it much easier to convert 476 into other formats. This is done 477 by hitting the addend. */ 478 if (r->relent.howto->pc_relative) 479 r->relent.addend -= dst_ptr - dst_base_ptr; 480 } 481 break; 482 483 case RELOCATION_TYPE_UND: 484 { 485 oasys_reloc_type *r; 486 487 amt = sizeof (oasys_reloc_type); 488 r = bfd_alloc (abfd, amt); 489 if (!r) 490 return FALSE; 491 *(per->reloc_tail_ptr) = r; 492 per->reloc_tail_ptr = &r->next; 493 r->next = NULL; 494 /* Reference to undefined symbol. */ 495 src++; 496 /* Get symbol number. */ 497 r->symbol = (src[0] << 8) | src[1]; 498 /* Work out the howto. */ 499 abort (); 500 501 r->relent.addend = 0; 502 r->relent.address = dst_ptr - dst_base_ptr; 503 r->relent.howto = &howto_table[reloc >> 6]; 504 r->relent.sym_ptr_ptr = NULL; 505 section->reloc_count++; 506 507 src += 2; 508 /* Fake up the data to look like 509 it's got the -ve pc in it, this 510 makes it much easier to convert 511 into other formats. This is done 512 by hitting the addend. */ 513 if (r->relent.howto->pc_relative) 514 r->relent.addend -= dst_ptr - dst_base_ptr; 515 } 516 break; 517 case RELOCATION_TYPE_COM: 518 BFD_FAIL (); 519 } 520 } 521 *dst_ptr++ = *src++; 522 } 523 } 524 } 525 } 526 break; 527 case oasys_record_is_local_enum: 528 case oasys_record_is_symbol_enum: 529 case oasys_record_is_section_enum: 530 break; 531 default: 532 loop = FALSE; 533 } 534 } 535 536 return TRUE; 537 538 } 539 540 #define MAX_SECS 16 541 542 static const bfd_target * 543 oasys_object_p (bfd *abfd) 544 { 545 oasys_data_type *oasys; 546 oasys_data_type *save = OASYS_DATA (abfd); 547 bfd_boolean loop = TRUE; 548 bfd_boolean had_usefull = FALSE; 549 550 abfd->tdata.oasys_obj_data = 0; 551 oasys_mkobject (abfd); 552 oasys = OASYS_DATA (abfd); 553 memset ((void *) oasys->sections, 0xff, sizeof (oasys->sections)); 554 555 /* Point to the start of the file. */ 556 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 557 goto fail; 558 oasys->symbol_string_length = 0; 559 560 /* Inspect the records, but only keep the section info - 561 remember the size of the symbols. */ 562 oasys->first_data_record = 0; 563 while (loop) 564 { 565 oasys_record_union_type record; 566 if (! oasys_read_record (abfd, &record)) 567 goto fail; 568 if ((size_t) record.header.length < (size_t) sizeof (record.header)) 569 goto fail; 570 571 switch ((oasys_record_enum_type) (record.header.type)) 572 { 573 case oasys_record_is_header_enum: 574 had_usefull = TRUE; 575 break; 576 case oasys_record_is_symbol_enum: 577 case oasys_record_is_local_enum: 578 /* Count symbols and remember their size for a future malloc. */ 579 abfd->symcount++; 580 oasys->symbol_string_length += 1 + oasys_string_length (&record); 581 had_usefull = TRUE; 582 break; 583 case oasys_record_is_section_enum: 584 { 585 asection *s; 586 char *buffer; 587 unsigned int section_number; 588 589 if (record.section.header.length != sizeof (record.section)) 590 goto fail; 591 592 buffer = bfd_alloc (abfd, (bfd_size_type) 3); 593 if (!buffer) 594 goto fail; 595 section_number = record.section.relb & RELOCATION_SECT_BITS; 596 sprintf (buffer, "%u", section_number); 597 s = bfd_make_section (abfd, buffer); 598 oasys->sections[section_number] = s; 599 switch (record.section.relb & RELOCATION_TYPE_BITS) 600 { 601 case RELOCATION_TYPE_ABS: 602 case RELOCATION_TYPE_REL: 603 break; 604 case RELOCATION_TYPE_UND: 605 case RELOCATION_TYPE_COM: 606 BFD_FAIL (); 607 } 608 609 s->size = H_GET_32 (abfd, record.section.value); 610 s->vma = H_GET_32 (abfd, record.section.vma); 611 s->flags = 0; 612 had_usefull = TRUE; 613 } 614 break; 615 case oasys_record_is_data_enum: 616 oasys->first_data_record = bfd_tell (abfd) - record.header.length; 617 case oasys_record_is_debug_enum: 618 case oasys_record_is_module_enum: 619 case oasys_record_is_named_section_enum: 620 case oasys_record_is_end_enum: 621 if (! had_usefull) 622 goto fail; 623 loop = FALSE; 624 break; 625 default: 626 goto fail; 627 } 628 } 629 oasys->symbols = NULL; 630 631 /* Oasys support several architectures, but I can't see a simple way 632 to discover which one is in a particular file - we'll guess. */ 633 bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); 634 if (abfd->symcount != 0) 635 abfd->flags |= HAS_SYMS; 636 637 /* We don't know if a section has data until we've read it. */ 638 oasys_slurp_section_data (abfd); 639 640 return abfd->xvec; 641 642 fail: 643 (void) bfd_release (abfd, oasys); 644 abfd->tdata.oasys_obj_data = save; 645 return NULL; 646 } 647 648 649 static void 650 oasys_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, 651 asymbol *symbol, 652 symbol_info *ret) 653 { 654 bfd_symbol_info (symbol, ret); 655 656 if (!symbol->section) 657 ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; 658 } 659 660 static void 661 oasys_print_symbol (bfd *abfd, void * afile, asymbol *symbol, bfd_print_symbol_type how) 662 { 663 FILE *file = (FILE *) afile; 664 665 switch (how) 666 { 667 case bfd_print_symbol_name: 668 case bfd_print_symbol_more: 669 fprintf (file, "%s", symbol->name); 670 break; 671 case bfd_print_symbol_all: 672 { 673 const char *section_name = symbol->section == NULL ? 674 (const char *) "*abs" : symbol->section->name; 675 676 bfd_print_symbol_vandf (abfd, (void *) file, symbol); 677 678 fprintf (file, " %-5s %s", 679 section_name, 680 symbol->name); 681 } 682 break; 683 } 684 } 685 686 static bfd_boolean 687 oasys_new_section_hook (bfd *abfd, asection *newsect) 688 { 689 if (!newsect->used_by_bfd) 690 { 691 newsect->used_by_bfd 692 = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type)); 693 if (!newsect->used_by_bfd) 694 return FALSE; 695 } 696 oasys_per_section (newsect)->data = NULL; 697 oasys_per_section (newsect)->section = newsect; 698 oasys_per_section (newsect)->offset = 0; 699 oasys_per_section (newsect)->initialized = FALSE; 700 newsect->alignment_power = 1; 701 702 /* Turn the section string into an index. */ 703 sscanf (newsect->name, "%u", &newsect->target_index); 704 705 return _bfd_generic_new_section_hook (abfd, newsect); 706 } 707 708 709 static long 710 oasys_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) 711 { 712 if (! oasys_slurp_section_data (abfd)) 713 return -1; 714 return (asect->reloc_count + 1) * sizeof (arelent *); 715 } 716 717 static bfd_boolean 718 oasys_get_section_contents (bfd *abfd, 719 sec_ptr section, 720 void * location, 721 file_ptr offset, 722 bfd_size_type count) 723 { 724 oasys_per_section_type *p = oasys_per_section (section); 725 726 oasys_slurp_section_data (abfd); 727 728 if (! p->initialized) 729 (void) memset (location, 0, (size_t) count); 730 else 731 (void) memcpy (location, (void *) (p->data + offset), (size_t) count); 732 733 return TRUE; 734 } 735 736 static long 737 oasys_canonicalize_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED, 738 sec_ptr section, 739 arelent **relptr, 740 asymbol **symbols ATTRIBUTE_UNUSED) 741 { 742 unsigned int reloc_count = 0; 743 oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation); 744 745 if (src != NULL) 746 abort (); 747 748 *relptr = NULL; 749 return section->reloc_count = reloc_count; 750 } 751 752 753 /* Writing. */ 754 755 /* Calculate the checksum and write one record. */ 756 757 static bfd_boolean 758 oasys_write_record (bfd *abfd, 759 oasys_record_enum_type type, 760 oasys_record_union_type *record, 761 size_t size) 762 { 763 int checksum; 764 size_t i; 765 unsigned char *ptr; 766 767 record->header.length = size; 768 record->header.type = (int) type; 769 record->header.check_sum = 0; 770 record->header.fill = 0; 771 ptr = (unsigned char *) &record->pad[0]; 772 checksum = 0; 773 for (i = 0; i < size; i++) 774 checksum += *ptr++; 775 record->header.check_sum = 0xff & (-checksum); 776 if (bfd_bwrite ((void *) record, (bfd_size_type) size, abfd) != size) 777 return FALSE; 778 return TRUE; 779 } 780 781 782 /* Write out all the symbols. */ 783 784 static bfd_boolean 785 oasys_write_syms (bfd *abfd) 786 { 787 unsigned int count; 788 asymbol **generic = bfd_get_outsymbols (abfd); 789 unsigned int sym_index = 0; 790 791 for (count = 0; count < bfd_get_symcount (abfd); count++) 792 { 793 oasys_symbol_record_type symbol; 794 asymbol *const g = generic[count]; 795 const char *src = g->name; 796 char *dst = symbol.name; 797 unsigned int l = 0; 798 799 if (bfd_is_com_section (g->section)) 800 { 801 symbol.relb = RELOCATION_TYPE_COM; 802 H_PUT_16 (abfd, sym_index, symbol.refno); 803 sym_index++; 804 } 805 else if (bfd_is_abs_section (g->section)) 806 { 807 symbol.relb = RELOCATION_TYPE_ABS; 808 H_PUT_16 (abfd, 0, symbol.refno); 809 } 810 else if (bfd_is_und_section (g->section)) 811 { 812 symbol.relb = RELOCATION_TYPE_UND; 813 H_PUT_16 (abfd, sym_index, symbol.refno); 814 /* Overload the value field with the output sym_index number */ 815 sym_index++; 816 } 817 else if (g->flags & BSF_DEBUGGING) 818 /* Throw it away. */ 819 continue; 820 else 821 { 822 if (g->section == NULL) 823 /* Sometime, the oasys tools give out a symbol with illegal 824 bits in it, we'll output it in the same broken way. */ 825 symbol.relb = RELOCATION_TYPE_REL | 0; 826 else 827 symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index; 828 829 H_PUT_16 (abfd, 0, symbol.refno); 830 } 831 832 #ifdef UNDERSCORE_HACK 833 if (src[l] == '_') 834 dst[l++] = '.'; 835 #endif 836 while (src[l]) 837 { 838 dst[l] = src[l]; 839 l++; 840 } 841 842 H_PUT_32 (abfd, g->value, symbol.value); 843 844 if (g->flags & BSF_LOCAL) 845 { 846 if (! oasys_write_record (abfd, 847 oasys_record_is_local_enum, 848 (oasys_record_union_type *) & symbol, 849 offsetof (oasys_symbol_record_type, 850 name[0]) + l)) 851 return FALSE; 852 } 853 else 854 { 855 if (! oasys_write_record (abfd, 856 oasys_record_is_symbol_enum, 857 (oasys_record_union_type *) & symbol, 858 offsetof (oasys_symbol_record_type, 859 name[0]) + l)) 860 return FALSE; 861 } 862 g->value = sym_index - 1; 863 } 864 865 return TRUE; 866 } 867 868 /* Write a section header for each section. */ 869 870 static bfd_boolean 871 oasys_write_sections (bfd *abfd) 872 { 873 asection *s; 874 static oasys_section_record_type out; 875 876 for (s = abfd->sections; s != NULL; s = s->next) 877 { 878 if (!ISDIGIT (s->name[0])) 879 { 880 (*_bfd_error_handler) 881 (_("%s: can not represent section `%s' in oasys"), 882 bfd_get_filename (abfd), s->name); 883 bfd_set_error (bfd_error_nonrepresentable_section); 884 return FALSE; 885 } 886 out.relb = RELOCATION_TYPE_REL | s->target_index; 887 H_PUT_32 (abfd, s->size, out.value); 888 H_PUT_32 (abfd, s->vma, out.vma); 889 890 if (! oasys_write_record (abfd, 891 oasys_record_is_section_enum, 892 (oasys_record_union_type *) & out, 893 sizeof (out))) 894 return FALSE; 895 } 896 return TRUE; 897 } 898 899 static bfd_boolean 900 oasys_write_header (bfd *abfd) 901 { 902 /* Create and write the header. */ 903 oasys_header_record_type r; 904 size_t length = strlen (abfd->filename); 905 906 if (length > (size_t) sizeof (r.module_name)) 907 length = sizeof (r.module_name); 908 else if (length < (size_t) sizeof (r.module_name)) 909 (void) memset (r.module_name + length, ' ', 910 sizeof (r.module_name) - length); 911 912 (void) memcpy (r.module_name, abfd->filename, length); 913 914 r.version_number = OASYS_VERSION_NUMBER; 915 r.rev_number = OASYS_REV_NUMBER; 916 917 return oasys_write_record (abfd, oasys_record_is_header_enum, 918 (oasys_record_union_type *) & r, 919 offsetof (oasys_header_record_type, 920 description[0])); 921 } 922 923 static bfd_boolean 924 oasys_write_end (bfd *abfd) 925 { 926 oasys_end_record_type end; 927 unsigned char null = 0; 928 929 end.relb = RELOCATION_TYPE_ABS; 930 H_PUT_32 (abfd, abfd->start_address, end.entry); 931 H_PUT_16 (abfd, 0, end.fill); 932 end.zero = 0; 933 if (! oasys_write_record (abfd, 934 oasys_record_is_end_enum, 935 (oasys_record_union_type *) & end, 936 sizeof (end))) 937 return FALSE; 938 939 return bfd_bwrite ((void *) &null, (bfd_size_type) 1, abfd) == 1; 940 } 941 942 static int 943 comp (const void * ap, const void * bp) 944 { 945 arelent *a = *((arelent **) ap); 946 arelent *b = *((arelent **) bp); 947 948 return a->address - b->address; 949 } 950 951 static bfd_boolean 952 oasys_write_data (bfd *abfd) 953 { 954 asection *s; 955 956 for (s = abfd->sections; s != NULL; s = s->next) 957 { 958 if (s->flags & SEC_LOAD) 959 { 960 bfd_byte *raw_data = oasys_per_section (s)->data; 961 oasys_data_record_type processed_data; 962 bfd_size_type current_byte_index = 0; 963 unsigned int relocs_to_go = s->reloc_count; 964 arelent **p = s->orelocation; 965 966 if (s->reloc_count != 0) 967 /* Sort the reloc records so it's easy to insert the relocs into the 968 data. */ 969 qsort (s->orelocation, s->reloc_count, sizeof (arelent **), comp); 970 971 current_byte_index = 0; 972 processed_data.relb = s->target_index | RELOCATION_TYPE_REL; 973 974 while (current_byte_index < s->size) 975 { 976 /* Scan forwards by eight bytes or however much is left and see if 977 there are any relocations going on. */ 978 bfd_byte *mod = &processed_data.data[0]; 979 bfd_byte *dst = &processed_data.data[1]; 980 981 unsigned int i = 0; 982 *mod = 0; 983 984 H_PUT_32 (abfd, s->vma + current_byte_index, 985 processed_data.addr); 986 987 /* Don't start a relocation unless you're sure you can finish it 988 within the same data record. The worst case relocation is a 989 4-byte relocatable value which is split across two modification 990 bytes (1 relocation byte + 2 symbol reference bytes + 2 data + 991 1 modification byte + 2 data = 8 bytes total). That's where 992 the magic number 8 comes from. */ 993 while (current_byte_index < s->size && dst <= 994 & processed_data.data[sizeof (processed_data.data) - 8]) 995 { 996 if (relocs_to_go != 0) 997 { 998 arelent *r = *p; 999 1000 /* There is a relocation, is it for this byte ? */ 1001 if (r->address == current_byte_index) 1002 abort (); 1003 } 1004 1005 /* If this is coming from an unloadable section then copy 1006 zeros. */ 1007 if (raw_data == NULL) 1008 *dst++ = 0; 1009 else 1010 *dst++ = *raw_data++; 1011 1012 if (++i >= 8) 1013 { 1014 i = 0; 1015 mod = dst++; 1016 *mod = 0; 1017 } 1018 current_byte_index++; 1019 } 1020 1021 /* Don't write a useless null modification byte. */ 1022 if (dst == mod + 1) 1023 --dst; 1024 1025 if (! (oasys_write_record 1026 (abfd, oasys_record_is_data_enum, 1027 ((oasys_record_union_type *) &processed_data), 1028 (size_t) (dst - (bfd_byte *) &processed_data)))) 1029 return FALSE; 1030 } 1031 } 1032 } 1033 1034 return TRUE; 1035 } 1036 1037 static bfd_boolean 1038 oasys_write_object_contents (bfd *abfd) 1039 { 1040 if (! oasys_write_header (abfd)) 1041 return FALSE; 1042 if (! oasys_write_syms (abfd)) 1043 return FALSE; 1044 if (! oasys_write_sections (abfd)) 1045 return FALSE; 1046 if (! oasys_write_data (abfd)) 1047 return FALSE; 1048 if (! oasys_write_end (abfd)) 1049 return FALSE; 1050 return TRUE; 1051 } 1052 1053 /* Set section contents is complicated with OASYS since the format is 1054 not a byte image, but a record stream. */ 1055 1056 static bfd_boolean 1057 oasys_set_section_contents (bfd *abfd, 1058 sec_ptr section, 1059 const void * location, 1060 file_ptr offset, 1061 bfd_size_type count) 1062 { 1063 if (count != 0) 1064 { 1065 if (oasys_per_section (section)->data == NULL) 1066 { 1067 oasys_per_section (section)->data = bfd_alloc (abfd, section->size); 1068 if (!oasys_per_section (section)->data) 1069 return FALSE; 1070 } 1071 (void) memcpy ((void *) (oasys_per_section (section)->data + offset), 1072 location, (size_t) count); 1073 } 1074 return TRUE; 1075 } 1076 1077 1078 1079 /* Native-level interface to symbols. */ 1080 1081 /* We read the symbols into a buffer, which is discarded when this 1082 function exits. We read the strings into a buffer large enough to 1083 hold them all plus all the cached symbol entries. */ 1084 1085 static asymbol * 1086 oasys_make_empty_symbol (bfd *abfd) 1087 { 1088 bfd_size_type amt = sizeof (oasys_symbol_type); 1089 oasys_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt); 1090 1091 if (!new_symbol_type) 1092 return NULL; 1093 new_symbol_type->symbol.the_bfd = abfd; 1094 return &new_symbol_type->symbol; 1095 } 1096 1097 /* User should have checked the file flags; perhaps we should return 1098 BFD_NO_MORE_SYMBOLS if there are none? */ 1099 1100 static bfd * 1101 oasys_openr_next_archived_file (bfd *arch, bfd *prev) 1102 { 1103 oasys_ar_data_type *ar = OASYS_AR_DATA (arch); 1104 oasys_module_info_type *p; 1105 1106 /* Take the next one from the arch state, or reset. */ 1107 if (prev == NULL) 1108 /* Reset the index - the first two entries are bogus. */ 1109 ar->module_index = 0; 1110 1111 p = ar->module + ar->module_index; 1112 ar->module_index++; 1113 1114 if (ar->module_index <= ar->module_count) 1115 { 1116 if (p->abfd == NULL) 1117 { 1118 p->abfd = _bfd_create_empty_archive_element_shell (arch); 1119 p->abfd->origin = p->pos; 1120 p->abfd->filename = xstrdup (p->name); 1121 1122 /* Fixup a pointer to this element for the member. */ 1123 p->abfd->arelt_data = (void *) p; 1124 } 1125 return p->abfd; 1126 } 1127 1128 bfd_set_error (bfd_error_no_more_archived_files); 1129 return NULL; 1130 } 1131 1132 #define oasys_find_nearest_line _bfd_nosymbols_find_nearest_line 1133 #define oasys_find_line _bfd_nosymbols_find_line 1134 #define oasys_find_inliner_info _bfd_nosymbols_find_inliner_info 1135 1136 static int 1137 oasys_generic_stat_arch_elt (bfd *abfd, struct stat *buf) 1138 { 1139 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data; 1140 1141 if (mod == NULL) 1142 { 1143 bfd_set_error (bfd_error_invalid_operation); 1144 return -1; 1145 } 1146 1147 buf->st_size = mod->size; 1148 buf->st_mode = 0666; 1149 return 0; 1150 } 1151 1152 static int 1153 oasys_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, 1154 struct bfd_link_info *info ATTRIBUTE_UNUSED) 1155 { 1156 return 0; 1157 } 1158 1159 #define oasys_close_and_cleanup _bfd_generic_close_and_cleanup 1160 #define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info 1161 #define oasys_slurp_armap bfd_true 1162 #define oasys_slurp_extended_name_table bfd_true 1163 #define oasys_construct_extended_name_table ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_true) 1164 #define oasys_truncate_arname bfd_dont_truncate_arname 1165 #define oasys_write_armap ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) bfd_true) 1166 #define oasys_read_ar_hdr bfd_nullvoidptr 1167 #define oasys_write_ar_hdr ((bfd_boolean (*) (bfd *, bfd *)) bfd_false) 1168 #define oasys_get_elt_at_index _bfd_generic_get_elt_at_index 1169 #define oasys_update_armap_timestamp bfd_true 1170 #define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name 1171 #define oasys_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) 1172 #define oasys_get_lineno _bfd_nosymbols_get_lineno 1173 #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 1174 #define oasys_read_minisymbols _bfd_generic_read_minisymbols 1175 #define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol 1176 #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 1177 #define oasys_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup 1178 #define oasys_set_arch_mach bfd_default_set_arch_mach 1179 #define oasys_get_section_contents_in_window _bfd_generic_get_section_contents_in_window 1180 #define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents 1181 #define oasys_bfd_relax_section bfd_generic_relax_section 1182 #define oasys_bfd_gc_sections bfd_generic_gc_sections 1183 #define oasys_bfd_lookup_section_flags bfd_generic_lookup_section_flags 1184 #define oasys_bfd_merge_sections bfd_generic_merge_sections 1185 #define oasys_bfd_is_group_section bfd_generic_is_group_section 1186 #define oasys_bfd_discard_group bfd_generic_discard_group 1187 #define oasys_section_already_linked _bfd_generic_section_already_linked 1188 #define oasys_bfd_define_common_symbol bfd_generic_define_common_symbol 1189 #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 1190 #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols 1191 #define oasys_bfd_link_just_syms _bfd_generic_link_just_syms 1192 #define oasys_bfd_copy_link_hash_symbol_type \ 1193 _bfd_generic_copy_link_hash_symbol_type 1194 #define oasys_bfd_final_link _bfd_generic_final_link 1195 #define oasys_bfd_link_split_section _bfd_generic_link_split_section 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