This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / bfd / coff-tic80.c
1 /* BFD back-end for Texas Instruments TMS320C80 Multimedia Video Processor (MVP).
2    Copyright 1996, 1997 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 2 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
24
25 #include "bfd.h"
26 #include "bfdlink.h"
27 #include "sysdep.h"
28 #include "libbfd.h"
29 #include "coff/tic80.h"
30 #include "coff/internal.h"
31 #include "libcoff.h"
32
33 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
34 #define COFF_ALIGN_IN_SECTION_HEADER 1
35
36 #define GET_SCNHDR_FLAGS bfd_h_get_16
37 #define PUT_SCNHDR_FLAGS bfd_h_put_16
38
39 static void rtype2howto
40   PARAMS ((arelent *cache_ptr, struct internal_reloc *dst));
41 static bfd_reloc_status_type ppbase_reloc
42   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
43 static bfd_reloc_status_type glob15_reloc
44   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
45 static bfd_reloc_status_type glob16_reloc
46   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
47 static bfd_reloc_status_type local16_reloc
48   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
49 static boolean coff_tic80_relocate_section
50   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
51            struct internal_reloc *, struct internal_syment *, asection **));
52
53 static reloc_howto_type tic80_howto_table[] =
54 {
55
56   HOWTO (R_RELLONG,                     /* type */
57          0,                             /* rightshift */
58          2,                             /* size (0 = byte, 1 = short, 2 = long) */
59          32,                            /* bitsize */
60          false,                         /* pc_relative */
61          0,                             /* bitpos */
62          complain_overflow_bitfield,    /* complain_on_overflow */
63          NULL,                          /* special_function */
64          "RELLONG",                     /* name */
65          true,                          /* partial_inplace */
66          0xffffffff,                    /* src_mask */
67          0xffffffff,                    /* dst_mask */
68          false),                        /* pcrel_offset */
69
70   HOWTO (R_MPPCR,                       /* type */
71          2,                             /* rightshift */
72          2,                             /* size (0 = byte, 1 = short, 2 = long) */
73          32,                            /* bitsize */
74          true,                          /* pc_relative */
75          0,                             /* bitpos */
76          complain_overflow_signed,      /* complain_on_overflow */
77          NULL,                          /* special_function */
78          "MPPCR",                       /* name */
79          true,                          /* partial_inplace */
80          0xffffffff,                    /* src_mask */
81          0xffffffff,                    /* dst_mask */
82          true),                         /* pcrel_offset */
83
84   HOWTO (R_ABS,                         /* type */
85          0,                             /* rightshift */
86          2,                             /* size (0 = byte, 1 = short, 2 = long) */
87          32,                            /* bitsize */
88          false,                         /* pc_relative */
89          0,                             /* bitpos */
90          complain_overflow_bitfield,    /* complain_on_overflow */
91          NULL,                          /* special_function */
92          "ABS",                         /* name */
93          true,                          /* partial_inplace */
94          0xffffffff,                    /* src_mask */
95          0xffffffff,                    /* dst_mask */
96          false),                                /* pcrel_offset */
97
98   HOWTO (R_PPBASE,                      /* type */
99          0,                             /* rightshift */
100          2,                             /* size (0 = byte, 1 = short, 2 = long) */
101          32,                            /* bitsize */
102          false,                         /* pc_relative */
103          0,                             /* bitpos */
104          complain_overflow_dont,        /* complain_on_overflow */
105          ppbase_reloc,                  /* special_function */
106          "PPBASE",                      /* name */
107          true,                          /* partial_inplace */
108          0xffffffff,                    /* src_mask */
109          0xffffffff,                    /* dst_mask */
110          false),                        /* pcrel_offset */
111
112   HOWTO (R_PPLBASE,                     /* type */
113          0,                             /* rightshift */
114          2,                             /* size (0 = byte, 1 = short, 2 = long) */
115          32,                            /* bitsize */
116          false,                         /* pc_relative */
117          0,                             /* bitpos */
118          complain_overflow_dont,        /* complain_on_overflow */
119          ppbase_reloc,                  /* special_function */
120          "PPLBASE",                     /* name */
121          true,                          /* partial_inplace */
122          0xffffffff,                    /* src_mask */
123          0xffffffff,                    /* dst_mask */
124          false),                        /* pcrel_offset */
125
126   HOWTO (R_PP15,                        /* type */
127          0,                             /* rightshift */
128          2,                             /* size (0 = byte, 1 = short, 2 = long) */
129          15,                            /* bitsize */
130          false,                         /* pc_relative */
131          6,                             /* bitpos */
132          complain_overflow_dont,        /* complain_on_overflow */
133          glob15_reloc,                  /* special_function */
134          "PP15",                        /* name */
135          true,                          /* partial_inplace */
136          0x1ffc0,                       /* src_mask */
137          0x1ffc0,                       /* dst_mask */
138          false),                        /* pcrel_offset */
139
140   HOWTO (R_PP15W,                       /* type */
141          2,                             /* rightshift */
142          2,                             /* size (0 = byte, 1 = short, 2 = long) */
143          15,                            /* bitsize */
144          false,                         /* pc_relative */
145          6,                             /* bitpos */
146          complain_overflow_dont,        /* complain_on_overflow */
147          glob15_reloc,                  /* special_function */
148          "PP15W",                       /* name */
149          true,                          /* partial_inplace */
150          0x1ffc0,                       /* src_mask */
151          0x1ffc0,                       /* dst_mask */
152          false),                        /* pcrel_offset */
153
154   HOWTO (R_PP15H,                       /* type */
155          1,                             /* rightshift */
156          2,                             /* size (0 = byte, 1 = short, 2 = long) */
157          15,                            /* bitsize */
158          false,                         /* pc_relative */
159          6,                             /* bitpos */
160          complain_overflow_dont,        /* complain_on_overflow */
161          glob15_reloc,                  /* special_function */
162          "PP15H",                       /* name */
163          true,                          /* partial_inplace */
164          0x1ffc0,                       /* src_mask */
165          0x1ffc0,                       /* dst_mask */
166          false),                        /* pcrel_offset */
167
168   HOWTO (R_PP16B,                       /* type */
169          0,                             /* rightshift */
170          2,                             /* size (0 = byte, 1 = short, 2 = long) */
171          16,                            /* bitsize */
172          false,                         /* pc_relative */
173          6,                             /* bitpos */
174          complain_overflow_dont,        /* complain_on_overflow */
175          glob16_reloc,                  /* special_function */
176          "PP16B",                       /* name */
177          true,                          /* partial_inplace */
178          0x3ffc0,                       /* src_mask */
179          0x3ffc0,                       /* dst_mask */
180          false),                        /* pcrel_offset */
181
182   HOWTO (R_PPL15,                       /* type */
183          0,                             /* rightshift */
184          2,                             /* size (0 = byte, 1 = short, 2 = long) */
185          15,                            /* bitsize */
186          false,                         /* pc_relative */
187          0,                             /* bitpos */
188          complain_overflow_dont,        /* complain_on_overflow */
189          NULL,                          /* special_function */
190          "PPL15",                       /* name */
191          true,                          /* partial_inplace */
192          0x7fff,                        /* src_mask */
193          0x7fff,                        /* dst_mask */
194          false),                        /* pcrel_offset */
195
196   HOWTO (R_PPL15W,                      /* type */
197          2,                             /* rightshift */
198          2,                             /* size (0 = byte, 1 = short, 2 = long) */
199          15,                            /* bitsize */
200          false,                         /* pc_relative */
201          0,                             /* bitpos */
202          complain_overflow_dont,        /* complain_on_overflow */
203          NULL,                          /* special_function */
204          "PPL15W",                      /* name */
205          true,                          /* partial_inplace */
206          0x7fff,                        /* src_mask */
207          0x7fff,                        /* dst_mask */
208          false),                        /* pcrel_offset */
209
210   HOWTO (R_PPL15H,                      /* type */
211          1,                             /* rightshift */
212          2,                             /* size (0 = byte, 1 = short, 2 = long) */
213          15,                            /* bitsize */
214          false,                         /* pc_relative */
215          0,                             /* bitpos */
216          complain_overflow_dont,        /* complain_on_overflow */
217          NULL,                          /* special_function */
218          "PPL15H",                      /* name */
219          true,                          /* partial_inplace */
220          0x7fff,                        /* src_mask */
221          0x7fff,                        /* dst_mask */
222          false),                        /* pcrel_offset */
223
224   HOWTO (R_PPL16B,                      /* type */
225          0,                             /* rightshift */
226          2,                             /* size (0 = byte, 1 = short, 2 = long) */
227          16,                            /* bitsize */
228          false,                         /* pc_relative */
229          0,                             /* bitpos */
230          complain_overflow_dont,        /* complain_on_overflow */
231          local16_reloc,                 /* special_function */
232          "PPL16B",                      /* name */
233          true,                          /* partial_inplace */
234          0xffff,                        /* src_mask */
235          0xffff,                        /* dst_mask */
236          false),                        /* pcrel_offset */
237
238   HOWTO (R_PPN15,                       /* type */
239          0,                             /* rightshift */
240          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
241          15,                            /* bitsize */
242          false,                         /* pc_relative */
243          6,                             /* bitpos */
244          complain_overflow_dont,        /* complain_on_overflow */
245          glob15_reloc,                  /* special_function */
246          "PPN15",                       /* name */
247          true,                          /* partial_inplace */
248          0x1ffc0,                       /* src_mask */
249          0x1ffc0,                       /* dst_mask */
250          false),                        /* pcrel_offset */
251
252   HOWTO (R_PPN15W,                      /* type */
253          2,                             /* rightshift */
254          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
255          15,                            /* bitsize */
256          false,                         /* pc_relative */
257          6,                             /* bitpos */
258          complain_overflow_dont,        /* complain_on_overflow */
259          glob15_reloc,                  /* special_function */
260          "PPN15W",                      /* name */
261          true,                          /* partial_inplace */
262          0x1ffc0,                       /* src_mask */
263          0x1ffc0,                       /* dst_mask */
264          false),                        /* pcrel_offset */
265
266   HOWTO (R_PPN15H,                      /* type */
267          1,                             /* rightshift */
268          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
269          15,                            /* bitsize */
270          false,                         /* pc_relative */
271          6,                             /* bitpos */
272          complain_overflow_dont,        /* complain_on_overflow */
273          glob15_reloc,                  /* special_function */
274          "PPN15H",                      /* name */
275          true,                          /* partial_inplace */
276          0x1ffc0,                       /* src_mask */
277          0x1ffc0,                       /* dst_mask */
278          false),                        /* pcrel_offset */
279
280   HOWTO (R_PPN16B,                      /* type */
281          0,                             /* rightshift */
282          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
283          16,                            /* bitsize */
284          false,                         /* pc_relative */
285          6,                             /* bitpos */
286          complain_overflow_dont,        /* complain_on_overflow */
287          glob16_reloc,                  /* special_function */
288          "PPN16B",                      /* name */
289          true,                          /* partial_inplace */
290          0x3ffc0,                       /* src_mask */
291          0x3ffc0,                       /* dst_mask */
292          false),                        /* pcrel_offset */
293
294   HOWTO (R_PPLN15,                      /* type */
295          0,                             /* rightshift */
296          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
297          15,                            /* bitsize */
298          false,                         /* pc_relative */
299          0,                             /* bitpos */
300          complain_overflow_dont,        /* complain_on_overflow */
301          NULL,                          /* special_function */
302          "PPLN15",                      /* name */
303          true,                          /* partial_inplace */
304          0x7fff,                        /* src_mask */
305          0x7fff,                        /* dst_mask */
306          false),                        /* pcrel_offset */
307
308   HOWTO (R_PPLN15W,                     /* type */
309          2,                             /* rightshift */
310          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
311          15,                            /* bitsize */
312          false,                         /* pc_relative */
313          0,                             /* bitpos */
314          complain_overflow_dont,        /* complain_on_overflow */
315          NULL,                          /* special_function */
316          "PPLN15W",                     /* name */
317          true,                          /* partial_inplace */
318          0x7fff,                        /* src_mask */
319          0x7fff,                        /* dst_mask */
320          false),                        /* pcrel_offset */
321
322   HOWTO (R_PPLN15H,                     /* type */
323          1,                             /* rightshift */
324          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
325          15,                            /* bitsize */
326          false,                         /* pc_relative */
327          0,                             /* bitpos */
328          complain_overflow_dont,        /* complain_on_overflow */
329          NULL,                          /* special_function */
330          "PPLN15H",                     /* name */
331          true,                          /* partial_inplace */
332          0x7fff,                        /* src_mask */
333          0x7fff,                        /* dst_mask */
334          false),                        /* pcrel_offset */
335
336   HOWTO (R_PPLN16B,                     /* type */
337          0,                             /* rightshift */
338          -2,                            /* size (0 = byte, 1 = short, 2 = long) */
339          15,                            /* bitsize */
340          false,                         /* pc_relative */
341          0,                             /* bitpos */
342          complain_overflow_dont,        /* complain_on_overflow */
343          local16_reloc,                 /* special_function */
344          "PPLN16B",                     /* name */
345          true,                          /* partial_inplace */
346          0xffff,                        /* src_mask */
347          0xffff,                        /* dst_mask */
348          false)                         /* pcrel_offset */
349 };
350 \f
351 /* Special relocation functions, used when the output file is not
352    itself a COFF TIc80 file.  */
353
354 /* This special function is used for the base address type
355    relocations.  */
356
357 static bfd_reloc_status_type
358 ppbase_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
359               error_message)
360      bfd *abfd;
361      arelent *reloc_entry;
362      asymbol *symbol_in;
363      PTR data;
364      asection *input_section;
365      bfd *output_bfd;
366      char **error_message;
367 {
368   /* FIXME.  */
369   abort ();
370 }
371
372 /* This special function is used for the global 15 bit relocations.  */
373
374 static bfd_reloc_status_type
375 glob15_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
376               error_message)
377      bfd *abfd;
378      arelent *reloc_entry;
379      asymbol *symbol_in;
380      PTR data;
381      asection *input_section;
382      bfd *output_bfd;
383      char **error_message;
384 {
385   /* FIXME.  */
386   abort ();
387 }
388
389 /* This special function is used for the global 16 bit relocations.  */
390
391 static bfd_reloc_status_type
392 glob16_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
393               error_message)
394      bfd *abfd;
395      arelent *reloc_entry;
396      asymbol *symbol_in;
397      PTR data;
398      asection *input_section;
399      bfd *output_bfd;
400      char **error_message;
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 (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
410               error_message)
411      bfd *abfd;
412      arelent *reloc_entry;
413      asymbol *symbol_in;
414      PTR data;
415      asection *input_section;
416      bfd *output_bfd;
417      char **error_message;
418 {
419   /* FIXME.  */
420   abort ();
421 }
422 \f
423 /* 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 (cache_ptr, dst)
429      arelent *cache_ptr;
430      struct internal_reloc *dst;
431 {
432   unsigned int i;
433
434   for (i = 0; i < sizeof tic80_howto_table / sizeof tic80_howto_table[0]; i++)
435     {
436       if (tic80_howto_table[i].type == dst->r_type)
437         {
438           cache_ptr->howto = tic80_howto_table + i;
439           return;
440         }
441     }
442
443   (*_bfd_error_handler) ("Unrecognized reloc type 0x%x",
444                          (unsigned int) dst->r_type);
445   cache_ptr->howto = tic80_howto_table + 0;
446 }
447
448 #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
449 #define coff_rtype_to_howto coff_tic80_rtype_to_howto
450
451 static reloc_howto_type *
452 coff_tic80_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
453      bfd *abfd;
454      asection *sec;
455      struct internal_reloc *rel;
456      struct coff_link_hash_entry *h;
457      struct internal_syment *sym;
458      bfd_vma *addendp;
459 {
460   arelent genrel;
461
462   if (rel -> r_symndx == -1 && addendp != NULL)
463     {
464       /* This is a TI "internal relocation", which means that the relocation
465          amount is the amount by which the current section is being relocated
466          in the output section. */
467       *addendp = (sec -> output_section -> vma + sec -> output_offset) - sec -> vma;
468     }
469   RTYPE2HOWTO (&genrel, rel);
470   return genrel.howto;
471 }
472
473 #ifndef BADMAG
474 #define BADMAG(x) TIC80BADMAG(x)
475 #endif
476 \f
477 #define coff_relocate_section coff_tic80_relocate_section
478
479 /* We need a special relocation routine to handle the PP relocs.  Most
480    of this is a copy of _bfd_coff_generic_relocate_section.  */
481
482 static boolean
483 coff_tic80_relocate_section (output_bfd, info, input_bfd,
484                              input_section, contents, relocs, syms,
485                              sections)
486      bfd *output_bfd;
487      struct bfd_link_info *info;
488      bfd *input_bfd;
489      asection *input_section;
490      bfd_byte *contents;
491      struct internal_reloc *relocs;
492      struct internal_syment *syms;
493      asection **sections;
494 {
495   struct internal_reloc *rel;
496   struct internal_reloc *relend;
497
498   rel = relocs;
499   relend = rel + input_section->reloc_count;
500   for (; rel < relend; rel++)
501     {
502       long symndx;
503       struct coff_link_hash_entry *h;
504       struct internal_syment *sym;
505       bfd_vma addend;
506       bfd_vma val;
507       reloc_howto_type *howto;
508       bfd_reloc_status_type rstat;
509       bfd_vma addr;
510
511       symndx = rel->r_symndx;
512
513       if (symndx == -1)
514         {
515           h = NULL;
516           sym = NULL;
517         }
518       else
519         {    
520           h = obj_coff_sym_hashes (input_bfd)[symndx];
521           sym = syms + symndx;
522         }
523
524       /* COFF treats common symbols in one of two ways.  Either the
525          size of the symbol is included in the section contents, or it
526          is not.  We assume that the size is not included, and force
527          the rtype_to_howto function to adjust the addend as needed.  */
528
529       if (sym != NULL && sym->n_scnum != 0)
530         addend = - sym->n_value;
531       else
532         addend = 0;
533
534       howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
535                                        sym, &addend);
536       if (howto == NULL)
537         return false;
538
539       val = 0;
540
541       if (h == NULL)
542         {
543           asection *sec;
544
545           if (symndx == -1)
546             {
547               sec = bfd_abs_section_ptr;
548               val = 0;
549             }
550           else
551             {
552               sec = sections[symndx];
553               val = (sec->output_section->vma
554                      + sec->output_offset
555                      + sym->n_value);
556               if (! obj_pe (output_bfd))
557                 val -= sec->vma;
558             }
559         }
560       else
561         {
562           if (h->root.type == bfd_link_hash_defined
563               || h->root.type == bfd_link_hash_defweak)
564             {
565               asection *sec;
566
567               sec = h->root.u.def.section;
568               val = (h->root.u.def.value
569                      + sec->output_section->vma
570                      + sec->output_offset);
571               }
572
573           else if (! info->relocateable)
574             {
575               if (! ((*info->callbacks->undefined_symbol)
576                      (info, h->root.root.string, input_bfd, input_section,
577                       rel->r_vaddr - input_section->vma)))
578                 return false;
579             }
580         }
581
582       addr = rel->r_vaddr - input_section->vma;
583
584       /* FIXME: This code assumes little endian, but the PP can
585          apparently be bi-endian.  I don't know if the bi-endianness
586          applies to the instruction set or just to the data.  */
587       switch (howto->type)
588         {
589         default:
590         case R_ABS:
591         case R_RELLONGX:
592         case R_PPL15:
593         case R_PPL15W:
594         case R_PPL15H:
595         case R_PPLN15:
596         case R_PPLN15W:
597         case R_PPLN15H:
598           rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
599                                             contents, addr, val, addend);
600           break;
601
602         case R_PP15:
603         case R_PP15W:
604         case R_PP15H:
605         case R_PPN15:
606         case R_PPN15W:
607         case R_PPN15H:
608           /* Offset the address so that we can use 4 byte relocations.  */
609           rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
610                                             contents + 2, addr, val, addend);
611           break;
612
613         case R_PP16B:
614         case R_PPN16B:
615           {
616             /* The most significant bit is stored in bit 6.  */
617             bfd_byte hold;
618
619             hold = contents[addr + 4];
620             contents[addr + 4] &=~ 0x20;
621             contents[addr + 4] |= (contents[addr] >> 1) & 0x20;
622             rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
623                                               contents + 2, addr,
624                                               val, addend);
625             contents[addr] &=~ 0x40;
626             contents[addr] |= (contents[addr + 4] << 1) & 0x40;
627             contents[addr + 4] &=~ 0x20;
628             contents[addr + 4] |= hold & 0x20;
629             break;
630           }
631
632         case R_PPL16B:
633         case R_PPLN16B:
634           {
635             /* The most significant bit is stored in bit 28.  */
636             bfd_byte hold;
637
638             hold = contents[addr + 1];
639             contents[addr + 1] &=~ 0x80;
640             contents[addr + 1] |= (contents[addr + 3] << 3) & 0x80;
641             rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
642                                               contents, addr,
643                                               val, addend);
644             contents[addr + 3] &= ~0x10;
645             contents[addr + 3] |= (contents[addr + 1] >> 3) & 0x10;
646             contents[addr + 1] &=~ 0x80;
647             contents[addr + 1] |= hold & 0x80;
648             break;
649           }
650         
651         case R_PPBASE:
652           /* Parameter RAM is from 0x1000000 to 0x1000800.  */
653           contents[addr] &=~ 0x3;
654           if (val >= 0x1000000 && val < 0x1000800)
655             contents[addr] |= 0x3;
656           else
657             contents[addr] |= 0x2;
658           rstat = bfd_reloc_ok;
659           break;
660
661         case R_PPLBASE:
662           /* Parameter RAM is from 0x1000000 to 0x1000800.  */
663           contents[addr + 2] &= ~0xc0;
664           if (val >= 0x1000000 && val < 0x1000800)
665             contents[addr + 2] |= 0xc0;
666           else
667             contents[addr + 2] |= 0x80;
668           rstat = bfd_reloc_ok;
669           break;
670         }
671
672       switch (rstat)
673         {
674         default:
675           abort ();
676         case bfd_reloc_ok:
677           break;
678         case bfd_reloc_outofrange:
679           (*_bfd_error_handler)
680             ("%s: bad reloc address 0x%lx in section `%s'",
681              bfd_get_filename (input_bfd),
682              (unsigned long) rel->r_vaddr,
683              bfd_get_section_name (input_bfd, input_section));
684           return false;
685         case bfd_reloc_overflow:
686           {
687             const char *name;
688             char buf[SYMNMLEN + 1];
689
690             if (symndx == -1)
691               name = "*ABS*";
692             else if (h != NULL)
693               name = h->root.root.string;
694             else
695               {
696                 name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
697                 if (name == NULL)
698                   return false;
699               }
700
701             if (! ((*info->callbacks->reloc_overflow)
702                    (info, name, howto->name, (bfd_vma) 0, input_bfd,
703                     input_section, rel->r_vaddr - input_section->vma)))
704               return false;
705           }
706         }
707     }
708   return true;
709 }
710 \f
711 #define TIC80COFF 1             /* Customize coffcode.h */
712 #undef C_AUTOARG                /* Clashes with TIc80's C_UEXT */
713 #undef C_LASTENT                /* Clashes with TIc80's C_STATLAB */
714 #include "coffcode.h"
715
716 const bfd_target 
717   tic80coff_vec =
718 {
719   "coff-tic80",                 /* name */
720   bfd_target_coff_flavour,
721   BFD_ENDIAN_LITTLE,            /* data byte order is little (arch supports both) */
722   BFD_ENDIAN_LITTLE,            /* header byte order is little */
723
724   (HAS_RELOC | EXEC_P |         /* object flags */
725    HAS_LINENO | HAS_DEBUG |
726    HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
727
728   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
729   '_',                          /* leading underscore */
730   '/',                          /* ar_pad_char */
731   15,                           /* ar_max_namelen */
732   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
733      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
734      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
735   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
736      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
737      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
738
739  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
740    bfd_generic_archive_p, _bfd_dummy_target},
741  {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
742    bfd_false},
743  {bfd_false, coff_write_object_contents, /* bfd_write_contents */
744    _bfd_write_archive_contents, bfd_false},
745
746      BFD_JUMP_TABLE_GENERIC (coff),
747      BFD_JUMP_TABLE_COPY (coff),
748      BFD_JUMP_TABLE_CORE (_bfd_nocore),
749      BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
750      BFD_JUMP_TABLE_SYMBOLS (coff),
751      BFD_JUMP_TABLE_RELOCS (coff),
752      BFD_JUMP_TABLE_WRITE (coff),
753      BFD_JUMP_TABLE_LINK (coff),
754      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
755
756   COFF_SWAP_TABLE
757  };