ns32k: remove dupplicate definition of input_line_pointer
[external/binutils.git] / bfd / coff-tic80.c
1 /* BFD back-end for Texas Instruments TMS320C80 Multimedia Video Processor (MVP).
2    Copyright (C) 1996-2016 Free Software Foundation, Inc.
3
4    Written by Fred Fish (fnf@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 \f
357 /* Special relocation functions, used when the output file is not
358    itself a COFF TIc80 file.  */
359
360 /* This special function is used for the base address type
361    relocations.  */
362
363 static bfd_reloc_status_type
364 ppbase_reloc (bfd *abfd ATTRIBUTE_UNUSED,
365               arelent *reloc_entry ATTRIBUTE_UNUSED,
366               asymbol *symbol_in ATTRIBUTE_UNUSED,
367               void * data ATTRIBUTE_UNUSED,
368               asection *input_section ATTRIBUTE_UNUSED,
369               bfd *output_bfd ATTRIBUTE_UNUSED,
370               char **error_message ATTRIBUTE_UNUSED)
371 {
372   /* FIXME.  */
373   abort ();
374 }
375
376 /* This special function is used for the global 15 bit relocations.  */
377
378 static bfd_reloc_status_type
379 glob15_reloc (bfd *abfd ATTRIBUTE_UNUSED,
380               arelent *reloc_entry ATTRIBUTE_UNUSED,
381               asymbol *symbol_in ATTRIBUTE_UNUSED,
382               void * data ATTRIBUTE_UNUSED,
383               asection *input_section ATTRIBUTE_UNUSED,
384               bfd *output_bfd ATTRIBUTE_UNUSED,
385               char **error_message ATTRIBUTE_UNUSED)
386 {
387   /* FIXME.  */
388   abort ();
389 }
390
391 /* This special function is used for the global 16 bit relocations.  */
392
393 static bfd_reloc_status_type
394 glob16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
395               arelent *reloc_entry ATTRIBUTE_UNUSED,
396               asymbol *symbol_in ATTRIBUTE_UNUSED,
397               void * data ATTRIBUTE_UNUSED,
398               asection *input_section ATTRIBUTE_UNUSED,
399               bfd *output_bfd ATTRIBUTE_UNUSED,
400               char **error_message ATTRIBUTE_UNUSED)
401 {
402   /* FIXME.  */
403   abort ();
404 }
405
406 /* This special function is used for the local 16 bit relocations.  */
407
408 static bfd_reloc_status_type
409 local16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
410                arelent *reloc_entry ATTRIBUTE_UNUSED,
411                asymbol *symbol_in ATTRIBUTE_UNUSED,
412                void * data ATTRIBUTE_UNUSED,
413                asection *input_section ATTRIBUTE_UNUSED,
414                bfd *output_bfd ATTRIBUTE_UNUSED,
415                char **error_message ATTRIBUTE_UNUSED)
416 {
417   /* FIXME.  */
418   abort ();
419 }
420 \f
421 /* Code to turn an external r_type into a pointer to an entry in the howto_table.
422    If passed an r_type we don't recognize the abort rather than silently failing
423    to generate an output file.  */
424
425 static void
426 rtype2howto (arelent *cache_ptr, struct internal_reloc *dst)
427 {
428   unsigned int i;
429
430   for (i = 0; i < sizeof tic80_howto_table / sizeof tic80_howto_table[0]; i++)
431     {
432       if (tic80_howto_table[i].type == dst->r_type)
433         {
434           cache_ptr->howto = tic80_howto_table + i;
435           return;
436         }
437     }
438
439   (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
440                          (unsigned int) dst->r_type);
441   cache_ptr->howto = tic80_howto_table + 0;
442 }
443
444 #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
445 #define coff_rtype_to_howto coff_tic80_rtype_to_howto
446
447 static reloc_howto_type *
448 coff_tic80_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
449                            asection *sec,
450                            struct internal_reloc *rel,
451                            struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
452                            struct internal_syment *sym ATTRIBUTE_UNUSED,
453                            bfd_vma *addendp)
454 {
455   arelent genrel;
456
457   if (rel -> r_symndx == -1 && addendp != NULL)
458     {
459       /* This is a TI "internal relocation", which means that the relocation
460          amount is the amount by which the current section is being relocated
461          in the output section.  */
462       *addendp = (sec -> output_section -> vma + sec -> output_offset) - sec -> vma;
463     }
464   RTYPE2HOWTO (&genrel, rel);
465   return genrel.howto;
466 }
467
468 #ifndef BADMAG
469 #define BADMAG(x) TIC80BADMAG(x)
470 #endif
471 \f
472 #define coff_relocate_section coff_tic80_relocate_section
473
474 /* We need a special relocation routine to handle the PP relocs.  Most
475    of this is a copy of _bfd_coff_generic_relocate_section.  */
476
477 static bfd_boolean
478 coff_tic80_relocate_section (bfd *output_bfd,
479                              struct bfd_link_info *info,
480                              bfd *input_bfd,
481                              asection *input_section,
482                              bfd_byte *contents,
483                              struct internal_reloc *relocs,
484                              struct internal_syment *syms,
485                              asection **sections)
486 {
487   struct internal_reloc *rel;
488   struct internal_reloc *relend;
489
490   rel = relocs;
491   relend = rel + input_section->reloc_count;
492   for (; rel < relend; rel++)
493     {
494       long symndx;
495       struct coff_link_hash_entry *h;
496       struct internal_syment *sym;
497       bfd_vma addend;
498       bfd_vma val;
499       reloc_howto_type *howto;
500       bfd_reloc_status_type rstat;
501       bfd_vma addr;
502
503       symndx = rel->r_symndx;
504
505       if (symndx == -1)
506         {
507           h = NULL;
508           sym = NULL;
509         }
510       else
511         {
512           h = obj_coff_sym_hashes (input_bfd)[symndx];
513           sym = syms + symndx;
514         }
515
516       /* COFF treats common symbols in one of two ways.  Either the
517          size of the symbol is included in the section contents, or it
518          is not.  We assume that the size is not included, and force
519          the rtype_to_howto function to adjust the addend as needed.  */
520
521       if (sym != NULL && sym->n_scnum != 0)
522         addend = - sym->n_value;
523       else
524         addend = 0;
525
526       howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
527                                        sym, &addend);
528       if (howto == NULL)
529         return FALSE;
530
531       val = 0;
532
533       if (h == NULL)
534         {
535           asection *sec;
536
537           if (symndx == -1)
538             {
539               sec = bfd_abs_section_ptr;
540               val = 0;
541             }
542           else
543             {
544               sec = sections[symndx];
545               val = (sec->output_section->vma
546                      + sec->output_offset
547                      + sym->n_value);
548               if (! obj_pe (output_bfd))
549                 val -= sec->vma;
550             }
551         }
552       else
553         {
554           if (h->root.type == bfd_link_hash_defined
555               || h->root.type == bfd_link_hash_defweak)
556             {
557               asection *sec;
558
559               sec = h->root.u.def.section;
560               val = (h->root.u.def.value
561                      + sec->output_section->vma
562                      + sec->output_offset);
563               }
564
565           else if (! bfd_link_relocatable (info))
566             (*info->callbacks->undefined_symbol)
567               (info, h->root.root.string, input_bfd, input_section,
568                rel->r_vaddr - input_section->vma, TRUE);
569         }
570
571       addr = rel->r_vaddr - input_section->vma;
572
573       /* FIXME: This code assumes little endian, but the PP can
574          apparently be bi-endian.  I don't know if the bi-endianness
575          applies to the instruction set or just to the data.  */
576       switch (howto->type)
577         {
578         default:
579         case R_ABS:
580         case R_RELLONGX:
581         case R_PPL15:
582         case R_PPL15W:
583         case R_PPL15H:
584         case R_PPLN15:
585         case R_PPLN15W:
586         case R_PPLN15H:
587           rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
588                                             contents, addr, val, addend);
589           break;
590
591         case R_PP15:
592         case R_PP15W:
593         case R_PP15H:
594         case R_PPN15:
595         case R_PPN15W:
596         case R_PPN15H:
597           /* Offset the address so that we can use 4 byte relocations.  */
598           rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
599                                             contents + 2, addr, val, addend);
600           break;
601
602         case R_PP16B:
603         case R_PPN16B:
604           {
605             /* The most significant bit is stored in bit 6.  */
606             bfd_byte hold;
607
608             hold = contents[addr + 4];
609             contents[addr + 4] &=~ 0x20;
610             contents[addr + 4] |= (contents[addr] >> 1) & 0x20;
611             rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
612                                               contents + 2, addr,
613                                               val, addend);
614             contents[addr] &=~ 0x40;
615             contents[addr] |= (contents[addr + 4] << 1) & 0x40;
616             contents[addr + 4] &=~ 0x20;
617             contents[addr + 4] |= hold & 0x20;
618             break;
619           }
620
621         case R_PPL16B:
622         case R_PPLN16B:
623           {
624             /* The most significant bit is stored in bit 28.  */
625             bfd_byte hold;
626
627             hold = contents[addr + 1];
628             contents[addr + 1] &=~ 0x80;
629             contents[addr + 1] |= (contents[addr + 3] << 3) & 0x80;
630             rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
631                                               contents, addr,
632                                               val, addend);
633             contents[addr + 3] &= ~0x10;
634             contents[addr + 3] |= (contents[addr + 1] >> 3) & 0x10;
635             contents[addr + 1] &=~ 0x80;
636             contents[addr + 1] |= hold & 0x80;
637             break;
638           }
639
640         case R_PPBASE:
641           /* Parameter RAM is from 0x1000000 to 0x1000800.  */
642           contents[addr] &=~ 0x3;
643           if (val >= 0x1000000 && val < 0x1000800)
644             contents[addr] |= 0x3;
645           else
646             contents[addr] |= 0x2;
647           rstat = bfd_reloc_ok;
648           break;
649
650         case R_PPLBASE:
651           /* Parameter RAM is from 0x1000000 to 0x1000800.  */
652           contents[addr + 2] &= ~0xc0;
653           if (val >= 0x1000000 && val < 0x1000800)
654             contents[addr + 2] |= 0xc0;
655           else
656             contents[addr + 2] |= 0x80;
657           rstat = bfd_reloc_ok;
658           break;
659         }
660
661       switch (rstat)
662         {
663         default:
664           abort ();
665         case bfd_reloc_ok:
666           break;
667         case bfd_reloc_outofrange:
668           (*_bfd_error_handler)
669             (_("%B: bad reloc address 0x%lx in section `%A'"),
670              input_bfd, input_section, (unsigned long) rel->r_vaddr);
671           return FALSE;
672         case bfd_reloc_overflow:
673           {
674             const char *name;
675             char buf[SYMNMLEN + 1];
676
677             if (symndx == -1)
678               name = "*ABS*";
679             else if (h != NULL)
680               name = NULL;
681             else
682               {
683                 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
684                 if (name == NULL)
685                   return FALSE;
686               }
687
688             (*info->callbacks->reloc_overflow)
689               (info, (h ? &h->root : NULL), name, howto->name,
690                (bfd_vma) 0, input_bfd, input_section,
691                rel->r_vaddr - input_section->vma);
692           }
693         }
694     }
695   return TRUE;
696 }
697 \f
698 #define TIC80COFF 1             /* Customize coffcode.h */
699 #undef C_AUTOARG                /* Clashes with TIc80's C_UEXT */
700 #undef C_LASTENT                /* Clashes with TIc80's C_STATLAB */
701
702 #ifndef bfd_pe_print_pdata
703 #define bfd_pe_print_pdata      NULL
704 #endif
705
706 #include "coffcode.h"
707
708 CREATE_LITTLE_COFF_TARGET_VEC (tic80_coff_vec, "coff-tic80", D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)