1 /* BFD back-end for TMS320C30 a.out binaries. 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 3 Free Software Foundation, Inc. 4 Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au) 5 6 This file is part of BFD, the Binary File Descriptor library. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 21 02110-1301, USA. */ 22 23 #define TARGET_IS_BIG_ENDIAN_P 24 #define N_HEADER_IN_TEXT(x) 1 25 #define TEXT_START_ADDR 1024 26 #define TARGET_PAGE_SIZE 128 27 #define SEGMENT_SIZE TARGET_PAGE_SIZE 28 #define DEFAULT_ARCH bfd_arch_tic30 29 #define ARCH_SIZE 32 30 31 /* Do not "beautify" the CONCAT* macro args. Traditional C will not 32 remove whitespace added here, and thus will fail to concatenate 33 the tokens. */ 34 #define MY(OP) CONCAT2 (tic30_aout_,OP) 35 #define TARGETNAME "a.out-tic30" 36 #define NAME(x,y) CONCAT3 (tic30_aout,_32_,y) 37 38 #include "bfd.h" 39 #include "sysdep.h" 40 #include "libaout.h" 41 #include "aout/aout64.h" 42 #include "aout/stab_gnu.h" 43 #include "aout/ar.h" 44 45 #define MY_reloc_howto(BFD, REL, IN, EX, PC) tic30_aout_reloc_howto (BFD, REL, & IN, & EX, & PC) 46 47 #define MY_final_link_relocate tic30_aout_final_link_relocate 48 #define MY_object_p tic30_aout_object_p 49 #define MY_mkobject NAME (aout,mkobject) 50 #define MY_write_object_contents tic30_aout_write_object_contents 51 #define MY_set_sizes tic30_aout_set_sizes 52 53 #ifndef MY_exec_hdr_flags 54 #define MY_exec_hdr_flags 1 55 #endif 56 57 #ifndef MY_backend_data 58 59 #ifndef MY_zmagic_contiguous 60 #define MY_zmagic_contiguous 0 61 #endif 62 #ifndef MY_text_includes_header 63 #define MY_text_includes_header 0 64 #endif 65 #ifndef MY_entry_is_text_address 66 #define MY_entry_is_text_address 0 67 #endif 68 #ifndef MY_exec_header_not_counted 69 #define MY_exec_header_not_counted 1 70 #endif 71 #ifndef MY_add_dynamic_symbols 72 #define MY_add_dynamic_symbols 0 73 #endif 74 #ifndef MY_add_one_symbol 75 #define MY_add_one_symbol 0 76 #endif 77 #ifndef MY_link_dynamic_object 78 #define MY_link_dynamic_object 0 79 #endif 80 #ifndef MY_write_dynamic_symbol 81 #define MY_write_dynamic_symbol 0 82 #endif 83 #ifndef MY_check_dynamic_reloc 84 #define MY_check_dynamic_reloc 0 85 #endif 86 #ifndef MY_finish_dynamic_link 87 #define MY_finish_dynamic_link 0 88 #endif 89 90 static bfd_boolean 91 tic30_aout_set_sizes (bfd *abfd) 92 { 93 adata (abfd).page_size = TARGET_PAGE_SIZE; 94 95 #ifdef SEGMENT_SIZE 96 adata (abfd).segment_size = SEGMENT_SIZE; 97 #else 98 adata (abfd).segment_size = TARGET_PAGE_SIZE; 99 #endif 100 101 #ifdef ZMAGIC_DISK_BLOCK_SIZE 102 adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE; 103 #else 104 adata (abfd).zmagic_disk_block_size = TARGET_PAGE_SIZE; 105 #endif 106 107 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; 108 109 return TRUE; 110 } 111 112 static const struct aout_backend_data tic30_aout_backend_data = 113 { 114 MY_zmagic_contiguous, 115 MY_text_includes_header, 116 MY_entry_is_text_address, 117 MY_exec_hdr_flags, 118 0, /* Text vma? */ 119 MY_set_sizes, 120 MY_exec_header_not_counted, 121 MY_add_dynamic_symbols, 122 MY_add_one_symbol, 123 MY_link_dynamic_object, 124 MY_write_dynamic_symbol, 125 MY_check_dynamic_reloc, 126 MY_finish_dynamic_link 127 }; 128 #define MY_backend_data &tic30_aout_backend_data 129 #endif 130 131 static reloc_howto_type * 132 tic30_aout_reloc_howto (bfd *, struct reloc_std_external *, int *, int *, int *); 133 static bfd_reloc_status_type 134 tic30_aout_final_link_relocate 135 (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma, bfd_vma, bfd_vma); 136 137 /* FIXME: This is wrong. aoutx.h should really only be included by 138 aout32.c. */ 139 140 #include "aoutx.h" 141 142 /* This function is used to work out pc-relative offsets for the 143 TMS320C30. The data already placed by md_pcrel_from within gas is 144 useless for a relocation, so we just get the offset value and place 145 a version of this within the object code. 146 tic30_aout_final_link_relocate will then calculate the required 147 relocation to add on to the value in the object code. */ 148 149 static bfd_reloc_status_type 150 tic30_aout_fix_pcrel_16 (bfd *abfd, 151 arelent *reloc_entry, 152 asymbol *symbol ATTRIBUTE_UNUSED, 153 void * data, 154 asection *input_section ATTRIBUTE_UNUSED, 155 bfd *output_bfd ATTRIBUTE_UNUSED, 156 char **error_message ATTRIBUTE_UNUSED) 157 { 158 bfd_vma relocation = 1; 159 bfd_byte offset_data = bfd_get_8 (abfd, (bfd_byte *) data + reloc_entry->address - 1); 160 161 /* The byte before the location of the fix contains bits 23-16 of 162 the pcrel instruction. Bit 21 is set for a delayed instruction 163 which requires on offset of 3 instead of 1. */ 164 if (offset_data & 0x20) 165 relocation -= 3; 166 else 167 relocation -= 1; 168 bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address); 169 return bfd_reloc_ok; 170 } 171 172 /* This function is used as a callback for 16-bit relocs. This is 173 required for relocations between segments. A line in aoutx.h 174 requires that any relocations for the data section should point to 175 the end of the aligned text section, plus an offset. By default, 176 this does not happen, therefore this function takes care of 177 that. */ 178 179 static bfd_reloc_status_type 180 tic30_aout_fix_16 (bfd *abfd, 181 arelent *reloc_entry, 182 asymbol *symbol, 183 void * data, 184 asection *input_section ATTRIBUTE_UNUSED, 185 bfd *output_bfd, 186 char **error_message ATTRIBUTE_UNUSED) 187 { 188 bfd_vma relocation; 189 190 /* Make sure that the symbol's section is defined. */ 191 if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0) 192 return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined; 193 /* Get the size of the input section and turn it into the TMS320C30 194 32-bit address format. */ 195 relocation = (symbol->section->vma >> 2); 196 relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address); 197 bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address); 198 return bfd_reloc_ok; 199 } 200 201 /* This function does the same thing as tic30_aout_fix_16 except for 32 202 bit relocations. */ 203 204 static bfd_reloc_status_type 205 tic30_aout_fix_32 (bfd *abfd, 206 arelent *reloc_entry, 207 asymbol *symbol, 208 void * data, 209 asection *input_section ATTRIBUTE_UNUSED, 210 bfd *output_bfd, 211 char **error_message ATTRIBUTE_UNUSED) 212 { 213 bfd_vma relocation; 214 215 /* Make sure that the symbol's section is defined. */ 216 if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0) 217 return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined; 218 /* Get the size of the input section and turn it into the TMS320C30 219 32-bit address format. */ 220 relocation = (symbol->section->vma >> 2); 221 relocation += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); 222 bfd_put_32 (abfd, relocation, (bfd_byte *) data + reloc_entry->address); 223 return bfd_reloc_ok; 224 } 225 226 /* This table lists the relocation types for the TMS320C30. There are 227 only a few relocations required, and all must be divided by 4 (>> 228 2) to get the 32-bit addresses in the format the TMS320C30 likes 229 it. */ 230 reloc_howto_type tic30_aout_howto_table[] = 231 { 232 EMPTY_HOWTO (-1), 233 HOWTO (1, 2, 1, 16, FALSE, 0, 0, tic30_aout_fix_16, 234 "16", FALSE, 0x0000FFFF, 0x0000FFFF, FALSE), 235 HOWTO (2, 2, 2, 24, FALSE, 0, complain_overflow_bitfield, NULL, 236 "24", FALSE, 0x00FFFFFF, 0x00FFFFFF, FALSE), 237 HOWTO (3, 18, 3, 24, FALSE, 0, complain_overflow_bitfield, NULL, 238 "LDP", FALSE, 0x00FF0000, 0x000000FF, FALSE), 239 HOWTO (4, 2, 4, 32, FALSE, 0, complain_overflow_bitfield, tic30_aout_fix_32, 240 "32", FALSE, 0xFFFFFFFF, 0xFFFFFFFF, FALSE), 241 HOWTO (5, 2, 1, 16, TRUE, 0, complain_overflow_signed, 242 tic30_aout_fix_pcrel_16, "PCREL", TRUE, 0x0000FFFF, 0x0000FFFF, TRUE), 243 EMPTY_HOWTO (-1), 244 EMPTY_HOWTO (-1), 245 EMPTY_HOWTO (-1), 246 EMPTY_HOWTO (-1), 247 EMPTY_HOWTO (-1) 248 }; 249 250 251 static reloc_howto_type * 252 tic30_aout_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 253 bfd_reloc_code_real_type code) 254 { 255 switch (code) 256 { 257 case BFD_RELOC_8: 258 case BFD_RELOC_TIC30_LDP: 259 return &tic30_aout_howto_table[3]; 260 case BFD_RELOC_16: 261 return &tic30_aout_howto_table[1]; 262 case BFD_RELOC_24: 263 return &tic30_aout_howto_table[2]; 264 case BFD_RELOC_16_PCREL: 265 return &tic30_aout_howto_table[5]; 266 case BFD_RELOC_32: 267 return &tic30_aout_howto_table[4]; 268 default: 269 return NULL; 270 } 271 } 272 273 static reloc_howto_type * 274 tic30_aout_reloc_howto (bfd *abfd, 275 struct reloc_std_external *relocs, 276 int *r_index, 277 int *r_extern, 278 int *r_pcrel) 279 { 280 unsigned int r_length; 281 unsigned int r_pcrel_done; 282 int index; 283 284 *r_pcrel = 0; 285 if (bfd_header_big_endian (abfd)) 286 { 287 *r_index = ((relocs->r_index[0] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[2]); 288 *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); 289 r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); 290 r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG); 291 } 292 else 293 { 294 *r_index = ((relocs->r_index[2] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[0]); 295 *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); 296 r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); 297 r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE); 298 } 299 index = r_length + 4 * r_pcrel_done; 300 return tic30_aout_howto_table + index; 301 } 302 303 /* These macros will get 24-bit values from the bfd definition. 304 Big-endian only. */ 305 #define bfd_getb_24(BFD,ADDR) \ 306 (bfd_get_8 (BFD, ADDR ) << 16) | \ 307 (bfd_get_8 (BFD, ADDR + 1) << 8) | \ 308 (bfd_get_8 (BFD, ADDR + 2) ) 309 310 #define bfd_putb_24(BFD,DATA,ADDR) \ 311 bfd_put_8 (BFD, (bfd_byte) ((DATA >> 16) & 0xFF), ADDR ); \ 312 bfd_put_8 (BFD, (bfd_byte) ((DATA >> 8) & 0xFF), ADDR + 1); \ 313 bfd_put_8 (BFD, (bfd_byte) ( DATA & 0xFF), ADDR + 2) 314 315 /* Set parameters about this a.out file that are machine-dependent. 316 This routine is called from some_aout_object_p just before it returns. */ 317 318 static const bfd_target * 319 tic30_aout_callback (bfd *abfd) 320 { 321 struct internal_exec *execp = exec_hdr (abfd); 322 unsigned int arch_align_power; 323 unsigned long arch_align; 324 325 /* Calculate the file positions of the parts of a newly read aout header. */ 326 obj_textsec (abfd)->size = N_TXTSIZE (*execp); 327 328 /* The virtual memory addresses of the sections. */ 329 obj_textsec (abfd)->vma = N_TXTADDR (*execp); 330 obj_datasec (abfd)->vma = N_DATADDR (*execp); 331 obj_bsssec (abfd)->vma = N_BSSADDR (*execp); 332 333 obj_textsec (abfd)->lma = obj_textsec (abfd)->vma; 334 obj_datasec (abfd)->lma = obj_datasec (abfd)->vma; 335 obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma; 336 337 /* The file offsets of the sections. */ 338 obj_textsec (abfd)->filepos = N_TXTOFF (*execp); 339 obj_datasec (abfd)->filepos = N_DATOFF (*execp); 340 341 /* The file offsets of the relocation info. */ 342 obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp); 343 obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp); 344 345 /* The file offsets of the string table and symbol table. */ 346 obj_sym_filepos (abfd) = N_SYMOFF (*execp); 347 obj_str_filepos (abfd) = N_STROFF (*execp); 348 349 /* Determine the architecture and machine type of the object file. */ 350 #ifdef SET_ARCH_MACH 351 SET_ARCH_MACH (abfd, *execp); 352 #else 353 bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0L); 354 #endif 355 356 /* Now that we know the architecture, set the alignments of the 357 sections. This is normally done by NAME (aout,new_section_hook), 358 but when the initial sections were created the architecture had 359 not yet been set. However, for backward compatibility, we don't 360 set the alignment power any higher than as required by the size 361 of the section. */ 362 arch_align_power = bfd_get_arch_info (abfd)->section_align_power; 363 arch_align = 1 << arch_align_power; 364 if ((BFD_ALIGN (obj_textsec (abfd)->size, arch_align) 365 == obj_textsec (abfd)->size) 366 && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align) 367 == obj_datasec (abfd)->size) 368 && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align) 369 == obj_bsssec (abfd)->size)) 370 { 371 obj_textsec (abfd)->alignment_power = arch_align_power; 372 obj_datasec (abfd)->alignment_power = arch_align_power; 373 obj_bsssec (abfd)->alignment_power = arch_align_power; 374 } 375 return abfd->xvec; 376 } 377 378 static bfd_reloc_status_type 379 tic30_aout_relocate_contents (reloc_howto_type *howto, 380 bfd *input_bfd, 381 bfd_vma relocation, 382 bfd_byte *location) 383 { 384 bfd_vma x; 385 bfd_boolean overflow; 386 387 if (howto->size < 0) 388 relocation = -relocation; 389 390 switch (howto->size) 391 { 392 default: 393 case 0: 394 abort (); 395 break; 396 case 1: 397 x = bfd_get_16 (input_bfd, location); 398 break; 399 case 2: 400 x = bfd_getb_24 (input_bfd, location); 401 break; 402 case 3: 403 x = bfd_get_8 (input_bfd, location); 404 break; 405 case 4: 406 x = bfd_get_32 (input_bfd, location); 407 break; 408 } 409 410 overflow = FALSE; 411 412 if (howto->complain_on_overflow != complain_overflow_dont) 413 { 414 bfd_vma check; 415 bfd_signed_vma signed_check; 416 bfd_vma add; 417 bfd_signed_vma signed_add; 418 419 if (howto->rightshift == 0) 420 { 421 check = relocation; 422 signed_check = (bfd_signed_vma) relocation; 423 } 424 else 425 { 426 check = relocation >> howto->rightshift; 427 if ((bfd_signed_vma) relocation >= 0) 428 signed_check = check; 429 else 430 signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift))); 431 } 432 add = x & howto->src_mask; 433 signed_add = add; 434 if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0) 435 signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1; 436 if (howto->bitpos == 0) 437 { 438 check += add; 439 signed_check += signed_add; 440 } 441 else 442 { 443 check += add >> howto->bitpos; 444 if (signed_add >= 0) 445 signed_check += add >> howto->bitpos; 446 else 447 signed_check += ((add >> howto->bitpos) | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->bitpos))); 448 } 449 switch (howto->complain_on_overflow) 450 { 451 case complain_overflow_signed: 452 { 453 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; 454 bfd_signed_vma reloc_signed_min = ~reloc_signed_max; 455 456 if (signed_check > reloc_signed_max || signed_check < reloc_signed_min) 457 overflow = TRUE; 458 } 459 break; 460 case complain_overflow_unsigned: 461 { 462 bfd_vma reloc_unsigned_max = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; 463 464 if (check > reloc_unsigned_max) 465 overflow = TRUE; 466 } 467 break; 468 case complain_overflow_bitfield: 469 { 470 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; 471 472 if ((check & ~reloc_bits) != 0 473 && (((bfd_vma) signed_check & ~reloc_bits) 474 != ((bfd_vma) -1 & ~reloc_bits))) 475 overflow = TRUE; 476 } 477 break; 478 default: 479 abort (); 480 } 481 } 482 relocation >>= (bfd_vma) howto->rightshift; 483 relocation <<= (bfd_vma) howto->bitpos; 484 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)); 485 switch (howto->size) 486 { 487 default: 488 case 0: 489 abort (); 490 break; 491 case 1: 492 bfd_put_16 (input_bfd, x, location); 493 break; 494 case 2: 495 bfd_putb_24 (input_bfd, x, location); 496 break; 497 case 3: 498 bfd_put_8 (input_bfd, x, location); 499 break; 500 case 4: 501 bfd_put_32 (input_bfd, x, location); 502 break; 503 } 504 return overflow ? bfd_reloc_overflow : bfd_reloc_ok; 505 } 506 507 static bfd_reloc_status_type 508 tic30_aout_final_link_relocate (reloc_howto_type *howto, 509 bfd *input_bfd, 510 asection *input_section, 511 bfd_byte *contents, 512 bfd_vma address, 513 bfd_vma value, 514 bfd_vma addend) 515 { 516 bfd_vma relocation; 517 518 if (address > bfd_get_section_limit (input_bfd, input_section)) 519 return bfd_reloc_outofrange; 520 521 relocation = value + addend; 522 if (howto->pc_relative) 523 { 524 relocation -= (input_section->output_section->vma + input_section->output_offset); 525 if (howto->pcrel_offset) 526 relocation -= address; 527 } 528 return tic30_aout_relocate_contents (howto, input_bfd, relocation, 529 contents + address); 530 } 531 532 /* Finish up the reading of an a.out file header. */ 533 534 static const bfd_target * 535 tic30_aout_object_p (bfd *abfd) 536 { 537 struct external_exec exec_bytes; /* Raw exec header from file. */ 538 struct internal_exec exec; /* Cleaned-up exec header. */ 539 const bfd_target *target; 540 bfd_size_type amt = EXEC_BYTES_SIZE; 541 542 if (bfd_bread (& exec_bytes, amt, abfd) != amt) 543 { 544 if (bfd_get_error () != bfd_error_system_call) 545 bfd_set_error (bfd_error_wrong_format); 546 return 0; 547 } 548 549 #ifdef SWAP_MAGIC 550 exec.a_info = SWAP_MAGIC (exec_bytes.e_info); 551 #else 552 exec.a_info = H_GET_32 (abfd, exec_bytes.e_info); 553 #endif /* SWAP_MAGIC */ 554 555 if (N_BADMAG (exec)) 556 return 0; 557 #ifdef MACHTYPE_OK 558 if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) 559 return 0; 560 #endif 561 562 NAME (aout, swap_exec_header_in) (abfd, &exec_bytes, &exec); 563 564 #ifdef SWAP_MAGIC 565 /* Swap_exec_header_in read in a_info with the wrong byte order. */ 566 exec.a_info = SWAP_MAGIC (exec_bytes.e_info); 567 #endif 568 569 target = NAME (aout, some_aout_object_p) (abfd, &exec, tic30_aout_callback); 570 571 #ifdef ENTRY_CAN_BE_ZERO 572 /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage) 573 means that it isn't obvious if EXEC_P should be set. 574 All of the following must be true for an executable: 575 There must be no relocations, the bfd can be neither an 576 archive nor an archive element, and the file must be executable. */ 577 578 if (exec.a_trsize + exec.a_drsize == 0 579 && bfd_get_format (abfd) == bfd_object && abfd->my_archive == NULL) 580 { 581 struct stat buf; 582 #ifndef S_IXUSR 583 #define S_IXUSR 0100 /* Execute by owner. */ 584 #endif 585 if (stat (abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR)) 586 abfd->flags |= EXEC_P; 587 } 588 #endif 589 590 return target; 591 } 592 593 /* Copy private section data. This actually does nothing with the 594 sections. It copies the subformat field. We copy it here, because 595 we need to know whether this is a QMAGIC file before we set the 596 section contents, and copy_private_bfd_data is not called until 597 after the section contents have been set. */ 598 599 static bfd_boolean 600 MY_bfd_copy_private_section_data (bfd *ibfd, 601 asection *isec ATTRIBUTE_UNUSED, 602 bfd *obfd, 603 asection *osec ATTRIBUTE_UNUSED) 604 { 605 if (bfd_get_flavour (obfd) == bfd_target_aout_flavour) 606 obj_aout_subformat (obfd) = obj_aout_subformat (ibfd); 607 return TRUE; 608 } 609 610 /* Write an object file. 611 Section contents have already been written. We write the 612 file header, symbols, and relocation. */ 613 614 static bfd_boolean 615 tic30_aout_write_object_contents (bfd *abfd) 616 { 617 struct external_exec exec_bytes; 618 struct internal_exec *execp = exec_hdr (abfd); 619 620 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; 621 622 { 623 bfd_size_type text_size; /* Dummy vars. */ 624 file_ptr text_end; 625 626 if (adata (abfd).magic == undecided_magic) 627 NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end); 628 629 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; 630 execp->a_entry = bfd_get_start_address (abfd); 631 632 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * obj_reloc_entry_size (abfd)); 633 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * obj_reloc_entry_size (abfd)); 634 NAME (aout, swap_exec_header_out) (abfd, execp, &exec_bytes); 635 636 if (adata (abfd).exec_bytes_size > 0) 637 { 638 bfd_size_type amt; 639 640 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 641 return FALSE; 642 amt = adata (abfd).exec_bytes_size; 643 if (bfd_bwrite (& exec_bytes, amt, abfd) != amt) 644 return FALSE; 645 } 646 647 /* Now write out reloc info, followed by syms and strings. */ 648 if (bfd_get_outsymbols (abfd) != (asymbol **) NULL 649 && bfd_get_symcount (abfd) != 0) 650 { 651 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*execp)), SEEK_SET) != 0) 652 return FALSE; 653 654 if (!NAME (aout, write_syms) (abfd)) 655 return FALSE; 656 } 657 658 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0) 659 return FALSE; 660 if (!NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))) 661 return FALSE; 662 663 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0) 664 return FALSE; 665 if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd))) 666 return FALSE; 667 } 668 669 return TRUE; 670 } 671 672 #ifndef MY_final_link_callback 673 674 /* Callback for the final_link routine to set the section offsets. */ 675 676 static void 677 MY_final_link_callback (bfd *abfd, 678 file_ptr *ptreloff, 679 file_ptr *pdreloff, 680 file_ptr *psymoff) 681 { 682 struct internal_exec *execp = exec_hdr (abfd); 683 684 *ptreloff = obj_datasec (abfd)->filepos + execp->a_data; 685 *pdreloff = *ptreloff + execp->a_trsize; 686 *psymoff = *pdreloff + execp->a_drsize;; 687 } 688 689 #endif 690 691 #ifndef MY_bfd_final_link 692 693 /* Final link routine. We need to use a call back to get the correct 694 offsets in the output file. */ 695 696 static bfd_boolean 697 MY_bfd_final_link (bfd *abfd, struct bfd_link_info *info) 698 { 699 struct internal_exec *execp = exec_hdr (abfd); 700 file_ptr pos; 701 bfd_vma vma = 0; 702 int pad; 703 704 /* Set the executable header size to 0, as we don't want one for an 705 output. */ 706 adata (abfd).exec_bytes_size = 0; 707 pos = adata (abfd).exec_bytes_size; 708 /* Text. */ 709 vma = info->create_object_symbols_section->vma; 710 pos += vma; 711 obj_textsec (abfd)->filepos = pos; 712 obj_textsec (abfd)->vma = vma; 713 obj_textsec (abfd)->user_set_vma = 1; 714 pos += obj_textsec (abfd)->size; 715 vma += obj_textsec (abfd)->size; 716 717 /* Data. */ 718 if (abfd->flags & D_PAGED) 719 { 720 if (info->create_object_symbols_section->next->vma > 0) 721 obj_datasec (abfd)->vma = info->create_object_symbols_section->next->vma; 722 else 723 obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size); 724 } 725 else 726 obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4); 727 728 if (obj_datasec (abfd)->vma < vma) 729 obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4); 730 731 obj_datasec (abfd)->user_set_vma = 1; 732 vma = obj_datasec (abfd)->vma; 733 obj_datasec (abfd)->filepos = vma + adata (abfd).exec_bytes_size; 734 execp->a_text = vma - obj_textsec (abfd)->vma; 735 obj_textsec (abfd)->size = execp->a_text; 736 737 /* Since BSS follows data immediately, see if it needs alignment. */ 738 vma += obj_datasec (abfd)->size; 739 pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma; 740 obj_datasec (abfd)->size += pad; 741 pos += obj_datasec (abfd)->size; 742 execp->a_data = obj_datasec (abfd)->size; 743 744 /* BSS. */ 745 obj_bsssec (abfd)->vma = vma; 746 obj_bsssec (abfd)->user_set_vma = 1; 747 748 /* We are fully resized, so don't readjust in final_link. */ 749 adata (abfd).magic = z_magic; 750 751 return NAME (aout, final_link) (abfd, info, MY_final_link_callback); 752 } 753 754 #endif 755 756 static enum machine_type 757 tic30_aout_machine_type (enum bfd_architecture arch, 758 unsigned long machine ATTRIBUTE_UNUSED, 759 bfd_boolean *unknown) 760 { 761 enum machine_type arch_flags; 762 763 arch_flags = M_UNKNOWN; 764 *unknown = TRUE; 765 766 switch (arch) 767 { 768 case bfd_arch_tic30: 769 *unknown = FALSE; 770 break; 771 default: 772 arch_flags = M_UNKNOWN; 773 } 774 if (arch_flags != M_UNKNOWN) 775 *unknown = FALSE; 776 return arch_flags; 777 } 778 779 static bfd_boolean 780 tic30_aout_set_arch_mach (bfd *abfd, 781 enum bfd_architecture arch, 782 unsigned long machine) 783 { 784 if (!bfd_default_set_arch_mach (abfd, arch, machine)) 785 return FALSE; 786 if (arch != bfd_arch_unknown) 787 { 788 bfd_boolean unknown; 789 tic30_aout_machine_type (arch, machine, &unknown); 790 if (unknown) 791 return FALSE; 792 } 793 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; 794 return (*aout_backend_info (abfd)->set_sizes) (abfd); 795 } 796 797 /* We assume BFD generic archive files. */ 798 #ifndef MY_openr_next_archived_file 799 #define MY_openr_next_archived_file bfd_generic_openr_next_archived_file 800 #endif 801 #ifndef MY_get_elt_at_index 802 #define MY_get_elt_at_index _bfd_generic_get_elt_at_index 803 #endif 804 #ifndef MY_generic_stat_arch_elt 805 #define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt 806 #endif 807 #ifndef MY_slurp_armap 808 #define MY_slurp_armap bfd_slurp_bsd_armap 809 #endif 810 #ifndef MY_slurp_extended_name_table 811 #define MY_slurp_extended_name_table _bfd_slurp_extended_name_table 812 #endif 813 #ifndef MY_construct_extended_name_table 814 #define MY_construct_extended_name_table \ 815 _bfd_archive_bsd_construct_extended_name_table 816 #endif 817 #ifndef MY_write_armap 818 #define MY_write_armap bsd_write_armap 819 #endif 820 #ifndef MY_read_ar_hdr 821 #define MY_read_ar_hdr _bfd_generic_read_ar_hdr 822 #endif 823 #ifndef MY_truncate_arname 824 #define MY_truncate_arname bfd_bsd_truncate_arname 825 #endif 826 #ifndef MY_update_armap_timestamp 827 #define MY_update_armap_timestamp _bfd_archive_bsd_update_armap_timestamp 828 #endif 829 830 /* No core file defined here -- configure in trad-core.c separately. */ 831 #ifndef MY_core_file_failing_command 832 #define MY_core_file_failing_command _bfd_nocore_core_file_failing_command 833 #endif 834 #ifndef MY_core_file_failing_signal 835 #define MY_core_file_failing_signal _bfd_nocore_core_file_failing_signal 836 #endif 837 #ifndef MY_core_file_matches_executable_p 838 #define MY_core_file_matches_executable_p \ 839 _bfd_nocore_core_file_matches_executable_p 840 #endif 841 #ifndef MY_core_file_p 842 #define MY_core_file_p _bfd_dummy_target 843 #endif 844 845 #ifndef MY_bfd_debug_info_start 846 #define MY_bfd_debug_info_start bfd_void 847 #endif 848 #ifndef MY_bfd_debug_info_end 849 #define MY_bfd_debug_info_end bfd_void 850 #endif 851 #ifndef MY_bfd_debug_info_accumulate 852 #define MY_bfd_debug_info_accumulate \ 853 (void (*) (bfd*, struct bfd_section *)) bfd_void 854 #endif 855 856 #ifndef MY_core_file_failing_command 857 #define MY_core_file_failing_command NAME (aout, core_file_failing_command) 858 #endif 859 #ifndef MY_core_file_failing_signal 860 #define MY_core_file_failing_signal NAME (aout, core_file_failing_signal) 861 #endif 862 #ifndef MY_core_file_matches_executable_p 863 #define MY_core_file_matches_executable_p NAME (aout, core_file_matches_executable_p) 864 #endif 865 #ifndef MY_set_section_contents 866 #define MY_set_section_contents NAME (aout, set_section_contents) 867 #endif 868 #ifndef MY_get_section_contents 869 #define MY_get_section_contents aout_32_get_section_contents 870 #endif 871 #ifndef MY_get_section_contents_in_window 872 #define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window 873 #endif 874 #ifndef MY_new_section_hook 875 #define MY_new_section_hook NAME (aout, new_section_hook) 876 #endif 877 #ifndef MY_get_symtab_upper_bound 878 #define MY_get_symtab_upper_bound NAME (aout, get_symtab_upper_bound) 879 #endif 880 #ifndef MY_canonicalize_symtab 881 #define MY_canonicalize_symtab NAME (aout, canonicalize_symtab) 882 #endif 883 #ifndef MY_get_reloc_upper_bound 884 #define MY_get_reloc_upper_bound NAME (aout, get_reloc_upper_bound) 885 #endif 886 #ifndef MY_canonicalize_reloc 887 #define MY_canonicalize_reloc NAME (aout, canonicalize_reloc) 888 #endif 889 #ifndef MY_make_empty_symbol 890 #define MY_make_empty_symbol NAME (aout, make_empty_symbol) 891 #endif 892 #ifndef MY_print_symbol 893 #define MY_print_symbol NAME (aout, print_symbol) 894 #endif 895 #ifndef MY_get_symbol_info 896 #define MY_get_symbol_info NAME (aout, get_symbol_info) 897 #endif 898 #ifndef MY_get_lineno 899 #define MY_get_lineno NAME (aout, get_lineno) 900 #endif 901 #ifndef MY_set_arch_mach 902 #define MY_set_arch_mach tic30_aout_set_arch_mach 903 #endif 904 #ifndef MY_find_nearest_line 905 #define MY_find_nearest_line NAME (aout, find_nearest_line) 906 #endif 907 #ifndef MY_find_inliner_info 908 #define MY_find_inliner_info _bfd_nosymbols_find_inliner_info 909 #endif 910 #ifndef MY_sizeof_headers 911 #define MY_sizeof_headers NAME (aout, sizeof_headers) 912 #endif 913 #ifndef MY_bfd_get_relocated_section_contents 914 #define MY_bfd_get_relocated_section_contents \ 915 bfd_generic_get_relocated_section_contents 916 #endif 917 #ifndef MY_bfd_relax_section 918 #define MY_bfd_relax_section bfd_generic_relax_section 919 #endif 920 #ifndef MY_bfd_gc_sections 921 #define MY_bfd_gc_sections bfd_generic_gc_sections 922 #endif 923 #ifndef MY_bfd_merge_sections 924 #define MY_bfd_merge_sections bfd_generic_merge_sections 925 #endif 926 #ifndef MY_bfd_is_group_section 927 #define MY_bfd_is_group_section bfd_generic_is_group_section 928 #endif 929 #ifndef MY_bfd_discard_group 930 #define MY_bfd_discard_group bfd_generic_discard_group 931 #endif 932 #ifndef MY_section_already_linked 933 #define MY_section_already_linked \ 934 _bfd_generic_section_already_linked 935 #endif 936 #ifndef MY_bfd_reloc_type_lookup 937 #define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup 938 #endif 939 #ifndef MY_bfd_make_debug_symbol 940 #define MY_bfd_make_debug_symbol 0 941 #endif 942 #ifndef MY_read_minisymbols 943 #define MY_read_minisymbols NAME (aout, read_minisymbols) 944 #endif 945 #ifndef MY_minisymbol_to_symbol 946 #define MY_minisymbol_to_symbol NAME (aout, minisymbol_to_symbol) 947 #endif 948 #ifndef MY_bfd_link_hash_table_create 949 #define MY_bfd_link_hash_table_create NAME (aout, link_hash_table_create) 950 #endif 951 #ifndef MY_bfd_link_hash_table_free 952 #define MY_bfd_link_hash_table_free _bfd_generic_link_hash_table_free 953 #endif 954 #ifndef MY_bfd_link_add_symbols 955 #define MY_bfd_link_add_symbols NAME (aout, link_add_symbols) 956 #endif 957 #ifndef MY_bfd_link_just_syms 958 #define MY_bfd_link_just_syms _bfd_generic_link_just_syms 959 #endif 960 #ifndef MY_bfd_link_split_section 961 #define MY_bfd_link_split_section _bfd_generic_link_split_section 962 #endif 963 964 #ifndef MY_bfd_copy_private_bfd_data 965 #define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data 966 #endif 967 968 #ifndef MY_bfd_merge_private_bfd_data 969 #define MY_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data 970 #endif 971 972 #ifndef MY_bfd_copy_private_symbol_data 973 #define MY_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data 974 #endif 975 976 #ifndef MY_bfd_copy_private_header_data 977 #define MY_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data 978 #endif 979 980 #ifndef MY_bfd_print_private_bfd_data 981 #define MY_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data 982 #endif 983 984 #ifndef MY_bfd_set_private_flags 985 #define MY_bfd_set_private_flags _bfd_generic_bfd_set_private_flags 986 #endif 987 988 #ifndef MY_bfd_is_local_label_name 989 #define MY_bfd_is_local_label_name bfd_generic_is_local_label_name 990 #endif 991 992 #ifndef MY_bfd_is_target_special_symbol 993 #define MY_bfd_is_target_special_symbol \ 994 ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) 995 #endif 996 997 #ifndef MY_bfd_free_cached_info 998 #define MY_bfd_free_cached_info NAME (aout, bfd_free_cached_info) 999 #endif 1000 1001 #ifndef MY_close_and_cleanup 1002 #define MY_close_and_cleanup MY_bfd_free_cached_info 1003 #endif 1004 1005 #ifndef MY_get_dynamic_symtab_upper_bound 1006 #define MY_get_dynamic_symtab_upper_bound \ 1007 _bfd_nodynamic_get_dynamic_symtab_upper_bound 1008 #endif 1009 #ifndef MY_canonicalize_dynamic_symtab 1010 #define MY_canonicalize_dynamic_symtab \ 1011 _bfd_nodynamic_canonicalize_dynamic_symtab 1012 #endif 1013 #ifndef MY_get_synthetic_symtab 1014 #define MY_get_synthetic_symtab \ 1015 _bfd_nodynamic_get_synthetic_symtab 1016 #endif 1017 #ifndef MY_get_dynamic_reloc_upper_bound 1018 #define MY_get_dynamic_reloc_upper_bound \ 1019 _bfd_nodynamic_get_dynamic_reloc_upper_bound 1020 #endif 1021 #ifndef MY_canonicalize_dynamic_reloc 1022 #define MY_canonicalize_dynamic_reloc \ 1023 _bfd_nodynamic_canonicalize_dynamic_reloc 1024 #endif 1025 1026 /* Aout symbols normally have leading underscores. */ 1027 #ifndef MY_symbol_leading_char 1028 #define MY_symbol_leading_char '_' 1029 #endif 1030 1031 /* Aout archives normally use spaces for padding. */ 1032 #ifndef AR_PAD_CHAR 1033 #define AR_PAD_CHAR ' ' 1034 #endif 1035 1036 #ifndef MY_BFD_TARGET 1037 const bfd_target tic30_aout_vec = 1038 { 1039 TARGETNAME, /* Name. */ 1040 bfd_target_aout_flavour, 1041 BFD_ENDIAN_BIG, /* Target byte order (big). */ 1042 BFD_ENDIAN_BIG, /* Target headers byte order (big). */ 1043 (HAS_RELOC | /* Object flags. */ 1044 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 1045 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ 1046 MY_symbol_leading_char, 1047 AR_PAD_CHAR, /* AR_pad_char. */ 1048 15, /* AR_max_namelen. */ 1049 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1050 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1051 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ 1052 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1053 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1054 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ 1055 {_bfd_dummy_target, MY_object_p, /* bfd_check_format. */ 1056 bfd_generic_archive_p, MY_core_file_p}, 1057 {bfd_false, MY_mkobject, /* bfd_set_format. */ 1058 _bfd_generic_mkarchive, bfd_false}, 1059 {bfd_false, MY_write_object_contents, /* bfd_write_contents. */ 1060 _bfd_write_archive_contents, bfd_false}, 1061 1062 BFD_JUMP_TABLE_GENERIC (MY), 1063 BFD_JUMP_TABLE_COPY (MY), 1064 BFD_JUMP_TABLE_CORE (MY), 1065 BFD_JUMP_TABLE_ARCHIVE (MY), 1066 BFD_JUMP_TABLE_SYMBOLS (MY), 1067 BFD_JUMP_TABLE_RELOCS (MY), 1068 BFD_JUMP_TABLE_WRITE (MY), 1069 BFD_JUMP_TABLE_LINK (MY), 1070 BFD_JUMP_TABLE_DYNAMIC (MY), 1071 1072 NULL, 1073 1074 MY_backend_data 1075 }; 1076 #endif /* MY_BFD_TARGET */ 1077