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