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