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