1 /* BFD back-end for Texas Instruments TMS320C80 Multimedia Video Processor (MVP). 2 Copyright (C) 1996-2014 Free Software Foundation, Inc. 3 4 Written by Fred Fish (fnf (at) cygnus.com) 5 6 There is nothing new under the sun. This file draws a lot on other 7 coff files. 8 9 This file is part of BFD, the Binary File Descriptor library. 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, 51 Franklin Street - Fifth Floor, 24 Boston, MA 02110-1301, USA. */ 25 26 #include "sysdep.h" 27 #include "bfd.h" 28 #include "bfdlink.h" 29 #include "libbfd.h" 30 #ifdef _CONST 31 /* Newlib-based hosts define _CONST as a STDC-safe alias for const, 32 but to the tic80 toolchain it means something altogether different. 33 Since sysdep.h will have pulled in stdio.h and hence _ansi.h which 34 contains this definition, we must undef it before including the 35 tic80-specific definition. */ 36 #undef _CONST 37 #endif /* _CONST */ 38 #include "coff/tic80.h" 39 #include "coff/internal.h" 40 #include "libcoff.h" 41 42 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) 43 #define COFF_ALIGN_IN_SECTION_HEADER 1 44 #define COFF_ALIGN_IN_SFLAGS 1 45 46 #define GET_SCNHDR_FLAGS H_GET_16 47 #define PUT_SCNHDR_FLAGS H_PUT_16 48 49 static bfd_reloc_status_type ppbase_reloc 50 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 51 static bfd_reloc_status_type glob15_reloc 52 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 53 static bfd_reloc_status_type glob16_reloc 54 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 55 static bfd_reloc_status_type local16_reloc 56 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 57 58 59 static reloc_howto_type tic80_howto_table[] = 60 { 61 62 HOWTO (R_RELLONG, /* type */ 63 0, /* rightshift */ 64 2, /* size (0 = byte, 1 = short, 2 = long) */ 65 32, /* bitsize */ 66 FALSE, /* pc_relative */ 67 0, /* bitpos */ 68 complain_overflow_bitfield, /* complain_on_overflow */ 69 NULL, /* special_function */ 70 "RELLONG", /* name */ 71 TRUE, /* partial_inplace */ 72 0xffffffff, /* src_mask */ 73 0xffffffff, /* dst_mask */ 74 FALSE), /* pcrel_offset */ 75 76 HOWTO (R_MPPCR, /* type */ 77 2, /* rightshift */ 78 2, /* size (0 = byte, 1 = short, 2 = long) */ 79 32, /* bitsize */ 80 TRUE, /* pc_relative */ 81 0, /* bitpos */ 82 complain_overflow_signed, /* complain_on_overflow */ 83 NULL, /* special_function */ 84 "MPPCR", /* name */ 85 TRUE, /* partial_inplace */ 86 0xffffffff, /* src_mask */ 87 0xffffffff, /* dst_mask */ 88 TRUE), /* pcrel_offset */ 89 90 HOWTO (R_ABS, /* type */ 91 0, /* rightshift */ 92 2, /* size (0 = byte, 1 = short, 2 = long) */ 93 32, /* bitsize */ 94 FALSE, /* pc_relative */ 95 0, /* bitpos */ 96 complain_overflow_bitfield, /* complain_on_overflow */ 97 NULL, /* special_function */ 98 "ABS", /* name */ 99 TRUE, /* partial_inplace */ 100 0xffffffff, /* src_mask */ 101 0xffffffff, /* dst_mask */ 102 FALSE), /* pcrel_offset */ 103 104 HOWTO (R_PPBASE, /* type */ 105 0, /* rightshift */ 106 2, /* size (0 = byte, 1 = short, 2 = long) */ 107 32, /* bitsize */ 108 FALSE, /* pc_relative */ 109 0, /* bitpos */ 110 complain_overflow_dont, /* complain_on_overflow */ 111 ppbase_reloc, /* special_function */ 112 "PPBASE", /* name */ 113 TRUE, /* partial_inplace */ 114 0xffffffff, /* src_mask */ 115 0xffffffff, /* dst_mask */ 116 FALSE), /* pcrel_offset */ 117 118 HOWTO (R_PPLBASE, /* type */ 119 0, /* rightshift */ 120 2, /* size (0 = byte, 1 = short, 2 = long) */ 121 32, /* bitsize */ 122 FALSE, /* pc_relative */ 123 0, /* bitpos */ 124 complain_overflow_dont, /* complain_on_overflow */ 125 ppbase_reloc, /* special_function */ 126 "PPLBASE", /* name */ 127 TRUE, /* partial_inplace */ 128 0xffffffff, /* src_mask */ 129 0xffffffff, /* dst_mask */ 130 FALSE), /* pcrel_offset */ 131 132 HOWTO (R_PP15, /* type */ 133 0, /* rightshift */ 134 2, /* size (0 = byte, 1 = short, 2 = long) */ 135 15, /* bitsize */ 136 FALSE, /* pc_relative */ 137 6, /* bitpos */ 138 complain_overflow_dont, /* complain_on_overflow */ 139 glob15_reloc, /* special_function */ 140 "PP15", /* name */ 141 TRUE, /* partial_inplace */ 142 0x1ffc0, /* src_mask */ 143 0x1ffc0, /* dst_mask */ 144 FALSE), /* pcrel_offset */ 145 146 HOWTO (R_PP15W, /* type */ 147 2, /* rightshift */ 148 2, /* size (0 = byte, 1 = short, 2 = long) */ 149 15, /* bitsize */ 150 FALSE, /* pc_relative */ 151 6, /* bitpos */ 152 complain_overflow_dont, /* complain_on_overflow */ 153 glob15_reloc, /* special_function */ 154 "PP15W", /* name */ 155 TRUE, /* partial_inplace */ 156 0x1ffc0, /* src_mask */ 157 0x1ffc0, /* dst_mask */ 158 FALSE), /* pcrel_offset */ 159 160 HOWTO (R_PP15H, /* type */ 161 1, /* rightshift */ 162 2, /* size (0 = byte, 1 = short, 2 = long) */ 163 15, /* bitsize */ 164 FALSE, /* pc_relative */ 165 6, /* bitpos */ 166 complain_overflow_dont, /* complain_on_overflow */ 167 glob15_reloc, /* special_function */ 168 "PP15H", /* name */ 169 TRUE, /* partial_inplace */ 170 0x1ffc0, /* src_mask */ 171 0x1ffc0, /* dst_mask */ 172 FALSE), /* pcrel_offset */ 173 174 HOWTO (R_PP16B, /* type */ 175 0, /* rightshift */ 176 2, /* size (0 = byte, 1 = short, 2 = long) */ 177 16, /* bitsize */ 178 FALSE, /* pc_relative */ 179 6, /* bitpos */ 180 complain_overflow_dont, /* complain_on_overflow */ 181 glob16_reloc, /* special_function */ 182 "PP16B", /* name */ 183 TRUE, /* partial_inplace */ 184 0x3ffc0, /* src_mask */ 185 0x3ffc0, /* dst_mask */ 186 FALSE), /* pcrel_offset */ 187 188 HOWTO (R_PPL15, /* type */ 189 0, /* rightshift */ 190 2, /* size (0 = byte, 1 = short, 2 = long) */ 191 15, /* bitsize */ 192 FALSE, /* pc_relative */ 193 0, /* bitpos */ 194 complain_overflow_dont, /* complain_on_overflow */ 195 NULL, /* special_function */ 196 "PPL15", /* name */ 197 TRUE, /* partial_inplace */ 198 0x7fff, /* src_mask */ 199 0x7fff, /* dst_mask */ 200 FALSE), /* pcrel_offset */ 201 202 HOWTO (R_PPL15W, /* type */ 203 2, /* rightshift */ 204 2, /* size (0 = byte, 1 = short, 2 = long) */ 205 15, /* bitsize */ 206 FALSE, /* pc_relative */ 207 0, /* bitpos */ 208 complain_overflow_dont, /* complain_on_overflow */ 209 NULL, /* special_function */ 210 "PPL15W", /* name */ 211 TRUE, /* partial_inplace */ 212 0x7fff, /* src_mask */ 213 0x7fff, /* dst_mask */ 214 FALSE), /* pcrel_offset */ 215 216 HOWTO (R_PPL15H, /* type */ 217 1, /* rightshift */ 218 2, /* size (0 = byte, 1 = short, 2 = long) */ 219 15, /* bitsize */ 220 FALSE, /* pc_relative */ 221 0, /* bitpos */ 222 complain_overflow_dont, /* complain_on_overflow */ 223 NULL, /* special_function */ 224 "PPL15H", /* name */ 225 TRUE, /* partial_inplace */ 226 0x7fff, /* src_mask */ 227 0x7fff, /* dst_mask */ 228 FALSE), /* pcrel_offset */ 229 230 HOWTO (R_PPL16B, /* type */ 231 0, /* rightshift */ 232 2, /* size (0 = byte, 1 = short, 2 = long) */ 233 16, /* bitsize */ 234 FALSE, /* pc_relative */ 235 0, /* bitpos */ 236 complain_overflow_dont, /* complain_on_overflow */ 237 local16_reloc, /* special_function */ 238 "PPL16B", /* name */ 239 TRUE, /* partial_inplace */ 240 0xffff, /* src_mask */ 241 0xffff, /* dst_mask */ 242 FALSE), /* pcrel_offset */ 243 244 HOWTO (R_PPN15, /* type */ 245 0, /* rightshift */ 246 -2, /* size (0 = byte, 1 = short, 2 = long) */ 247 15, /* bitsize */ 248 FALSE, /* pc_relative */ 249 6, /* bitpos */ 250 complain_overflow_dont, /* complain_on_overflow */ 251 glob15_reloc, /* special_function */ 252 "PPN15", /* name */ 253 TRUE, /* partial_inplace */ 254 0x1ffc0, /* src_mask */ 255 0x1ffc0, /* dst_mask */ 256 FALSE), /* pcrel_offset */ 257 258 HOWTO (R_PPN15W, /* type */ 259 2, /* rightshift */ 260 -2, /* size (0 = byte, 1 = short, 2 = long) */ 261 15, /* bitsize */ 262 FALSE, /* pc_relative */ 263 6, /* bitpos */ 264 complain_overflow_dont, /* complain_on_overflow */ 265 glob15_reloc, /* special_function */ 266 "PPN15W", /* name */ 267 TRUE, /* partial_inplace */ 268 0x1ffc0, /* src_mask */ 269 0x1ffc0, /* dst_mask */ 270 FALSE), /* pcrel_offset */ 271 272 HOWTO (R_PPN15H, /* type */ 273 1, /* rightshift */ 274 -2, /* size (0 = byte, 1 = short, 2 = long) */ 275 15, /* bitsize */ 276 FALSE, /* pc_relative */ 277 6, /* bitpos */ 278 complain_overflow_dont, /* complain_on_overflow */ 279 glob15_reloc, /* special_function */ 280 "PPN15H", /* name */ 281 TRUE, /* partial_inplace */ 282 0x1ffc0, /* src_mask */ 283 0x1ffc0, /* dst_mask */ 284 FALSE), /* pcrel_offset */ 285 286 HOWTO (R_PPN16B, /* type */ 287 0, /* rightshift */ 288 -2, /* size (0 = byte, 1 = short, 2 = long) */ 289 16, /* bitsize */ 290 FALSE, /* pc_relative */ 291 6, /* bitpos */ 292 complain_overflow_dont, /* complain_on_overflow */ 293 glob16_reloc, /* special_function */ 294 "PPN16B", /* name */ 295 TRUE, /* partial_inplace */ 296 0x3ffc0, /* src_mask */ 297 0x3ffc0, /* dst_mask */ 298 FALSE), /* pcrel_offset */ 299 300 HOWTO (R_PPLN15, /* type */ 301 0, /* rightshift */ 302 -2, /* size (0 = byte, 1 = short, 2 = long) */ 303 15, /* bitsize */ 304 FALSE, /* pc_relative */ 305 0, /* bitpos */ 306 complain_overflow_dont, /* complain_on_overflow */ 307 NULL, /* special_function */ 308 "PPLN15", /* name */ 309 TRUE, /* partial_inplace */ 310 0x7fff, /* src_mask */ 311 0x7fff, /* dst_mask */ 312 FALSE), /* pcrel_offset */ 313 314 HOWTO (R_PPLN15W, /* type */ 315 2, /* rightshift */ 316 -2, /* size (0 = byte, 1 = short, 2 = long) */ 317 15, /* bitsize */ 318 FALSE, /* pc_relative */ 319 0, /* bitpos */ 320 complain_overflow_dont, /* complain_on_overflow */ 321 NULL, /* special_function */ 322 "PPLN15W", /* name */ 323 TRUE, /* partial_inplace */ 324 0x7fff, /* src_mask */ 325 0x7fff, /* dst_mask */ 326 FALSE), /* pcrel_offset */ 327 328 HOWTO (R_PPLN15H, /* type */ 329 1, /* rightshift */ 330 -2, /* size (0 = byte, 1 = short, 2 = long) */ 331 15, /* bitsize */ 332 FALSE, /* pc_relative */ 333 0, /* bitpos */ 334 complain_overflow_dont, /* complain_on_overflow */ 335 NULL, /* special_function */ 336 "PPLN15H", /* name */ 337 TRUE, /* partial_inplace */ 338 0x7fff, /* src_mask */ 339 0x7fff, /* dst_mask */ 340 FALSE), /* pcrel_offset */ 341 342 HOWTO (R_PPLN16B, /* type */ 343 0, /* rightshift */ 344 -2, /* size (0 = byte, 1 = short, 2 = long) */ 345 15, /* bitsize */ 346 FALSE, /* pc_relative */ 347 0, /* bitpos */ 348 complain_overflow_dont, /* complain_on_overflow */ 349 local16_reloc, /* special_function */ 350 "PPLN16B", /* name */ 351 TRUE, /* partial_inplace */ 352 0xffff, /* src_mask */ 353 0xffff, /* dst_mask */ 354 FALSE) /* pcrel_offset */ 355 }; 356 357 /* Special relocation functions, used when the output file is not 359 itself a COFF TIc80 file. */ 360 361 /* This special function is used for the base address type 362 relocations. */ 363 364 static bfd_reloc_status_type 365 ppbase_reloc (bfd *abfd ATTRIBUTE_UNUSED, 366 arelent *reloc_entry ATTRIBUTE_UNUSED, 367 asymbol *symbol_in ATTRIBUTE_UNUSED, 368 void * data ATTRIBUTE_UNUSED, 369 asection *input_section ATTRIBUTE_UNUSED, 370 bfd *output_bfd ATTRIBUTE_UNUSED, 371 char **error_message ATTRIBUTE_UNUSED) 372 { 373 /* FIXME. */ 374 abort (); 375 } 376 377 /* This special function is used for the global 15 bit relocations. */ 378 379 static bfd_reloc_status_type 380 glob15_reloc (bfd *abfd ATTRIBUTE_UNUSED, 381 arelent *reloc_entry ATTRIBUTE_UNUSED, 382 asymbol *symbol_in ATTRIBUTE_UNUSED, 383 void * data ATTRIBUTE_UNUSED, 384 asection *input_section ATTRIBUTE_UNUSED, 385 bfd *output_bfd ATTRIBUTE_UNUSED, 386 char **error_message ATTRIBUTE_UNUSED) 387 { 388 /* FIXME. */ 389 abort (); 390 } 391 392 /* This special function is used for the global 16 bit relocations. */ 393 394 static bfd_reloc_status_type 395 glob16_reloc (bfd *abfd ATTRIBUTE_UNUSED, 396 arelent *reloc_entry ATTRIBUTE_UNUSED, 397 asymbol *symbol_in ATTRIBUTE_UNUSED, 398 void * data ATTRIBUTE_UNUSED, 399 asection *input_section ATTRIBUTE_UNUSED, 400 bfd *output_bfd ATTRIBUTE_UNUSED, 401 char **error_message ATTRIBUTE_UNUSED) 402 { 403 /* FIXME. */ 404 abort (); 405 } 406 407 /* This special function is used for the local 16 bit relocations. */ 408 409 static bfd_reloc_status_type 410 local16_reloc (bfd *abfd ATTRIBUTE_UNUSED, 411 arelent *reloc_entry ATTRIBUTE_UNUSED, 412 asymbol *symbol_in ATTRIBUTE_UNUSED, 413 void * data ATTRIBUTE_UNUSED, 414 asection *input_section ATTRIBUTE_UNUSED, 415 bfd *output_bfd ATTRIBUTE_UNUSED, 416 char **error_message ATTRIBUTE_UNUSED) 417 { 418 /* FIXME. */ 419 abort (); 420 } 421 422 /* Code to turn an external r_type into a pointer to an entry in the howto_table. 424 If passed an r_type we don't recognize the abort rather than silently failing 425 to generate an output file. */ 426 427 static void 428 rtype2howto (arelent *cache_ptr, struct internal_reloc *dst) 429 { 430 unsigned int i; 431 432 for (i = 0; i < sizeof tic80_howto_table / sizeof tic80_howto_table[0]; i++) 433 { 434 if (tic80_howto_table[i].type == dst->r_type) 435 { 436 cache_ptr->howto = tic80_howto_table + i; 437 return; 438 } 439 } 440 441 (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"), 442 (unsigned int) dst->r_type); 443 cache_ptr->howto = tic80_howto_table + 0; 444 } 445 446 #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst) 447 #define coff_rtype_to_howto coff_tic80_rtype_to_howto 448 449 static reloc_howto_type * 450 coff_tic80_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, 451 asection *sec, 452 struct internal_reloc *rel, 453 struct coff_link_hash_entry *h ATTRIBUTE_UNUSED, 454 struct internal_syment *sym ATTRIBUTE_UNUSED, 455 bfd_vma *addendp) 456 { 457 arelent genrel; 458 459 if (rel -> r_symndx == -1 && addendp != NULL) 460 { 461 /* This is a TI "internal relocation", which means that the relocation 462 amount is the amount by which the current section is being relocated 463 in the output section. */ 464 *addendp = (sec -> output_section -> vma + sec -> output_offset) - sec -> vma; 465 } 466 RTYPE2HOWTO (&genrel, rel); 467 return genrel.howto; 468 } 469 470 #ifndef BADMAG 471 #define BADMAG(x) TIC80BADMAG(x) 472 #endif 473 474 #define coff_relocate_section coff_tic80_relocate_section 476 477 /* We need a special relocation routine to handle the PP relocs. Most 478 of this is a copy of _bfd_coff_generic_relocate_section. */ 479 480 static bfd_boolean 481 coff_tic80_relocate_section (bfd *output_bfd, 482 struct bfd_link_info *info, 483 bfd *input_bfd, 484 asection *input_section, 485 bfd_byte *contents, 486 struct internal_reloc *relocs, 487 struct internal_syment *syms, 488 asection **sections) 489 { 490 struct internal_reloc *rel; 491 struct internal_reloc *relend; 492 493 rel = relocs; 494 relend = rel + input_section->reloc_count; 495 for (; rel < relend; rel++) 496 { 497 long symndx; 498 struct coff_link_hash_entry *h; 499 struct internal_syment *sym; 500 bfd_vma addend; 501 bfd_vma val; 502 reloc_howto_type *howto; 503 bfd_reloc_status_type rstat; 504 bfd_vma addr; 505 506 symndx = rel->r_symndx; 507 508 if (symndx == -1) 509 { 510 h = NULL; 511 sym = NULL; 512 } 513 else 514 { 515 h = obj_coff_sym_hashes (input_bfd)[symndx]; 516 sym = syms + symndx; 517 } 518 519 /* COFF treats common symbols in one of two ways. Either the 520 size of the symbol is included in the section contents, or it 521 is not. We assume that the size is not included, and force 522 the rtype_to_howto function to adjust the addend as needed. */ 523 524 if (sym != NULL && sym->n_scnum != 0) 525 addend = - sym->n_value; 526 else 527 addend = 0; 528 529 howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, 530 sym, &addend); 531 if (howto == NULL) 532 return FALSE; 533 534 val = 0; 535 536 if (h == NULL) 537 { 538 asection *sec; 539 540 if (symndx == -1) 541 { 542 sec = bfd_abs_section_ptr; 543 val = 0; 544 } 545 else 546 { 547 sec = sections[symndx]; 548 val = (sec->output_section->vma 549 + sec->output_offset 550 + sym->n_value); 551 if (! obj_pe (output_bfd)) 552 val -= sec->vma; 553 } 554 } 555 else 556 { 557 if (h->root.type == bfd_link_hash_defined 558 || h->root.type == bfd_link_hash_defweak) 559 { 560 asection *sec; 561 562 sec = h->root.u.def.section; 563 val = (h->root.u.def.value 564 + sec->output_section->vma 565 + sec->output_offset); 566 } 567 568 else if (! info->relocatable) 569 { 570 if (! ((*info->callbacks->undefined_symbol) 571 (info, h->root.root.string, input_bfd, input_section, 572 rel->r_vaddr - input_section->vma, TRUE))) 573 return FALSE; 574 } 575 } 576 577 addr = rel->r_vaddr - input_section->vma; 578 579 /* FIXME: This code assumes little endian, but the PP can 580 apparently be bi-endian. I don't know if the bi-endianness 581 applies to the instruction set or just to the data. */ 582 switch (howto->type) 583 { 584 default: 585 case R_ABS: 586 case R_RELLONGX: 587 case R_PPL15: 588 case R_PPL15W: 589 case R_PPL15H: 590 case R_PPLN15: 591 case R_PPLN15W: 592 case R_PPLN15H: 593 rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, 594 contents, addr, val, addend); 595 break; 596 597 case R_PP15: 598 case R_PP15W: 599 case R_PP15H: 600 case R_PPN15: 601 case R_PPN15W: 602 case R_PPN15H: 603 /* Offset the address so that we can use 4 byte relocations. */ 604 rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, 605 contents + 2, addr, val, addend); 606 break; 607 608 case R_PP16B: 609 case R_PPN16B: 610 { 611 /* The most significant bit is stored in bit 6. */ 612 bfd_byte hold; 613 614 hold = contents[addr + 4]; 615 contents[addr + 4] &=~ 0x20; 616 contents[addr + 4] |= (contents[addr] >> 1) & 0x20; 617 rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, 618 contents + 2, addr, 619 val, addend); 620 contents[addr] &=~ 0x40; 621 contents[addr] |= (contents[addr + 4] << 1) & 0x40; 622 contents[addr + 4] &=~ 0x20; 623 contents[addr + 4] |= hold & 0x20; 624 break; 625 } 626 627 case R_PPL16B: 628 case R_PPLN16B: 629 { 630 /* The most significant bit is stored in bit 28. */ 631 bfd_byte hold; 632 633 hold = contents[addr + 1]; 634 contents[addr + 1] &=~ 0x80; 635 contents[addr + 1] |= (contents[addr + 3] << 3) & 0x80; 636 rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, 637 contents, addr, 638 val, addend); 639 contents[addr + 3] &= ~0x10; 640 contents[addr + 3] |= (contents[addr + 1] >> 3) & 0x10; 641 contents[addr + 1] &=~ 0x80; 642 contents[addr + 1] |= hold & 0x80; 643 break; 644 } 645 646 case R_PPBASE: 647 /* Parameter RAM is from 0x1000000 to 0x1000800. */ 648 contents[addr] &=~ 0x3; 649 if (val >= 0x1000000 && val < 0x1000800) 650 contents[addr] |= 0x3; 651 else 652 contents[addr] |= 0x2; 653 rstat = bfd_reloc_ok; 654 break; 655 656 case R_PPLBASE: 657 /* Parameter RAM is from 0x1000000 to 0x1000800. */ 658 contents[addr + 2] &= ~0xc0; 659 if (val >= 0x1000000 && val < 0x1000800) 660 contents[addr + 2] |= 0xc0; 661 else 662 contents[addr + 2] |= 0x80; 663 rstat = bfd_reloc_ok; 664 break; 665 } 666 667 switch (rstat) 668 { 669 default: 670 abort (); 671 case bfd_reloc_ok: 672 break; 673 case bfd_reloc_outofrange: 674 (*_bfd_error_handler) 675 (_("%B: bad reloc address 0x%lx in section `%A'"), 676 input_bfd, input_section, (unsigned long) rel->r_vaddr); 677 return FALSE; 678 case bfd_reloc_overflow: 679 { 680 const char *name; 681 char buf[SYMNMLEN + 1]; 682 683 if (symndx == -1) 684 name = "*ABS*"; 685 else if (h != NULL) 686 name = NULL; 687 else 688 { 689 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); 690 if (name == NULL) 691 return FALSE; 692 } 693 694 if (! ((*info->callbacks->reloc_overflow) 695 (info, (h ? &h->root : NULL), name, howto->name, 696 (bfd_vma) 0, input_bfd, input_section, 697 rel->r_vaddr - input_section->vma))) 698 return FALSE; 699 } 700 } 701 } 702 return TRUE; 703 } 704 705 #define TIC80COFF 1 /* Customize coffcode.h */ 707 #undef C_AUTOARG /* Clashes with TIc80's C_UEXT */ 708 #undef C_LASTENT /* Clashes with TIc80's C_STATLAB */ 709 710 #ifndef bfd_pe_print_pdata 711 #define bfd_pe_print_pdata NULL 712 #endif 713 714 #include "coffcode.h" 715 716 CREATE_LITTLE_COFF_TARGET_VEC (tic80_coff_vec, "coff-tic80", D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE) 717