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