bfd/
[binutils.git] / bfd / elf32-bfin.c
blobc97cbb2044e80d3fae419ee3441ee87bf4e4bbf0
1 /* ADI Blackfin BFD support for 32-bit ELF.
2 Copyright 2005 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
19 USA. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/bfin.h"
27 /* Handling expression relocations for blackfin. Blackfin
28 will generate relocations in an expression form with a stack.
29 A relocation such as P1.H = _typenames-4000000;
30 will generate the following relocs at offset 4:
31 00000004 R_expst_push _typenames
32 00000004 R_expst_const .__constant
33 00000004 R_expst_sub .__operator
34 00000006 R_huimm16 .__operator
36 The .__constant and .__operator symbol names are fake.
37 Special case is a single relocation
38 P1.L = _typenames; generates
39 00000002 R_luimm16 _typenames
41 Thus, if you get a R_luimm16, R_huimm16, R_imm16,
42 if the stack is not empty, pop the stack and
43 put the value, else do the normal thing
44 We will currently assume that the max the stack
45 would grow to is 100. . */
47 #define RELOC_STACK_SIZE 100
48 static bfd_vma reloc_stack[RELOC_STACK_SIZE];
49 static unsigned int reloc_stack_tos = 0;
51 #define is_reloc_stack_empty() ((reloc_stack_tos > 0) ? 0 : 1)
53 static void
54 reloc_stack_push (bfd_vma value)
56 reloc_stack[reloc_stack_tos++] = value;
59 static bfd_vma
60 reloc_stack_pop (void)
62 return reloc_stack[--reloc_stack_tos];
65 static bfd_vma
66 reloc_stack_operate (unsigned int oper)
68 bfd_vma value;
69 switch (oper)
71 case R_add:
73 value =
74 reloc_stack[reloc_stack_tos - 2] + reloc_stack[reloc_stack_tos - 1];
75 reloc_stack_tos -= 2;
76 break;
78 case R_sub:
80 value =
81 reloc_stack[reloc_stack_tos - 2] - reloc_stack[reloc_stack_tos - 1];
82 reloc_stack_tos -= 2;
83 break;
85 case R_mult:
87 value =
88 reloc_stack[reloc_stack_tos - 2] * reloc_stack[reloc_stack_tos - 1];
89 reloc_stack_tos -= 2;
90 break;
92 case R_div:
94 if (reloc_stack[reloc_stack_tos - 1] == 0)
96 _bfd_abort (__FILE__, __LINE__, _("Division by zero. "));
98 else
100 value =
101 reloc_stack[reloc_stack_tos - 2] / reloc_stack[reloc_stack_tos - 1];
102 reloc_stack_tos -= 2;
104 break;
106 case R_mod:
108 value =
109 reloc_stack[reloc_stack_tos - 2] % reloc_stack[reloc_stack_tos - 1];
110 reloc_stack_tos -= 2;
111 break;
113 case R_lshift:
115 value =
116 reloc_stack[reloc_stack_tos - 2] << reloc_stack[reloc_stack_tos -
118 reloc_stack_tos -= 2;
119 break;
121 case R_rshift:
123 value =
124 reloc_stack[reloc_stack_tos - 2] >> reloc_stack[reloc_stack_tos -
126 reloc_stack_tos -= 2;
127 break;
129 case R_and:
131 value =
132 reloc_stack[reloc_stack_tos - 2] & reloc_stack[reloc_stack_tos - 1];
133 reloc_stack_tos -= 2;
134 break;
136 case R_or:
138 value =
139 reloc_stack[reloc_stack_tos - 2] | reloc_stack[reloc_stack_tos - 1];
140 reloc_stack_tos -= 2;
141 break;
143 case R_xor:
145 value =
146 reloc_stack[reloc_stack_tos - 2] ^ reloc_stack[reloc_stack_tos - 1];
147 reloc_stack_tos -= 2;
148 break;
150 case R_land:
152 value = reloc_stack[reloc_stack_tos - 2]
153 && reloc_stack[reloc_stack_tos - 1];
154 reloc_stack_tos -= 2;
155 break;
157 case R_lor:
159 value = reloc_stack[reloc_stack_tos - 2]
160 || reloc_stack[reloc_stack_tos - 1];
161 reloc_stack_tos -= 2;
162 break;
164 case R_neg:
166 value = -reloc_stack[reloc_stack_tos - 1];
167 reloc_stack_tos--;
168 break;
170 case R_comp:
172 value = ~reloc_stack[reloc_stack_tos - 1];
173 reloc_stack_tos -= 1;
174 break;
176 default:
178 fprintf (stderr, "bfin relocation : Internal bug\n");
179 return 0;
183 reloc_stack_push (value);
185 return value;
188 /* FUNCTION : bfin_pltpc_reloc
189 ABSTRACT : TODO : figure out how to handle pltpc relocs. */
190 static bfd_reloc_status_type
191 bfin_pltpc_reloc (
192 bfd *abfd ATTRIBUTE_UNUSED,
193 arelent *reloc_entry ATTRIBUTE_UNUSED,
194 asymbol *symbol ATTRIBUTE_UNUSED,
195 PTR data ATTRIBUTE_UNUSED,
196 asection *input_section ATTRIBUTE_UNUSED,
197 bfd *output_bfd ATTRIBUTE_UNUSED,
198 char **error_message ATTRIBUTE_UNUSED)
200 bfd_reloc_status_type flag = bfd_reloc_ok;
201 return flag;
205 static bfd_reloc_status_type
206 bfin_pcrel24_reloc (bfd *abfd,
207 arelent *reloc_entry,
208 asymbol *symbol,
209 PTR data,
210 asection *input_section,
211 bfd *output_bfd,
212 char **error_message ATTRIBUTE_UNUSED)
214 bfd_vma relocation;
215 bfd_size_type addr = reloc_entry->address;
216 bfd_vma output_base = 0;
217 reloc_howto_type *howto = reloc_entry->howto;
218 asection *output_section;
219 bfd_boolean relocatable = (output_bfd != NULL);
221 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
222 return bfd_reloc_outofrange;
224 if (!is_reloc_stack_empty ())
225 relocation = reloc_stack_pop();
226 else
228 if (bfd_is_und_section (symbol->section)
229 && (symbol->flags & BSF_WEAK) == 0
230 && !relocatable)
231 return bfd_reloc_undefined;
233 if (bfd_is_com_section (symbol->section))
234 relocation = 0;
235 else
236 relocation = symbol->value;
238 output_section = symbol->section->output_section;
240 if (relocatable)
241 output_base = 0;
242 else
243 output_base = output_section->vma;
245 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
246 relocation += output_base + symbol->section->output_offset;
248 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
249 relocation += reloc_entry->addend;
252 relocation -= input_section->output_section->vma + input_section->output_offset;
253 relocation -= reloc_entry->address;
255 if (howto->complain_on_overflow != complain_overflow_dont)
257 bfd_reloc_status_type status;
258 status= bfd_check_overflow (howto->complain_on_overflow,
259 howto->bitsize,
260 howto->rightshift,
261 bfd_arch_bits_per_address(abfd),
262 relocation);
263 if (status != bfd_reloc_ok)
264 return status;
267 /* if rightshift is 1 and the number odd, return error. */
268 if (howto->rightshift && (relocation & 0x01))
270 fprintf(stderr, "relocation should be even number\n");
271 return bfd_reloc_overflow;
274 relocation >>= (bfd_vma) howto->rightshift;
275 /* Shift everything up to where it's going to be used. */
277 relocation <<= (bfd_vma) howto->bitpos;
279 if (relocatable)
281 reloc_entry->address += input_section->output_offset;
282 reloc_entry->addend += symbol->section->output_offset;
286 short x;
288 /* We are getting reloc_entry->address 2 byte off from
289 the start of instruction. Assuming absolute postion
290 of the reloc data. But, following code had been written assuming
291 reloc address is starting at begining of instruction.
292 To compensate that I have increased the value of
293 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
295 relocation += 1;
296 x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
297 x = (x & 0xff00) | ((relocation >> 16) & 0xff);
298 bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);
300 x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
301 x = relocation & 0xFFFF;
302 bfd_put_16 (abfd, x, (unsigned char *) data + addr );
304 return bfd_reloc_ok;
307 static bfd_reloc_status_type
308 bfin_push_reloc (bfd *abfd ATTRIBUTE_UNUSED,
309 arelent *reloc_entry,
310 asymbol *symbol,
311 PTR data ATTRIBUTE_UNUSED,
312 asection *input_section,
313 bfd *output_bfd,
314 char **error_message ATTRIBUTE_UNUSED)
316 bfd_vma relocation;
317 bfd_vma output_base = 0;
318 asection *output_section;
319 bfd_boolean relocatable = (output_bfd != NULL);
321 if (bfd_is_und_section (symbol->section)
322 && (symbol->flags & BSF_WEAK) == 0
323 && !relocatable)
324 return bfd_reloc_undefined;
326 /* Is the address of the relocation really within the section? */
327 if (reloc_entry->address > bfd_get_section_limit(abfd, input_section))
328 return bfd_reloc_outofrange;
330 output_section = symbol->section->output_section;
331 relocation = symbol->value;
333 /* Convert input-section-relative symbol value to absolute. */
334 if (relocatable)
335 output_base = 0;
336 else
337 output_base = output_section->vma;
339 if (!relocatable || !strcmp(symbol->name, symbol->section->name))
340 relocation += output_base + symbol->section->output_offset;
342 /* Add in supplied addend. */
343 relocation += reloc_entry->addend;
345 if (relocatable)
347 reloc_entry->address += input_section->output_offset;
348 reloc_entry->addend += symbol->section->output_offset;
351 /* Now that we have the value, push it. */
352 reloc_stack_push (relocation);
354 return bfd_reloc_ok;
357 static bfd_reloc_status_type
358 bfin_oper_reloc (bfd *abfd ATTRIBUTE_UNUSED,
359 arelent *reloc_entry,
360 asymbol *symbol ATTRIBUTE_UNUSED,
361 PTR data ATTRIBUTE_UNUSED,
362 asection *input_section,
363 bfd *output_bfd,
364 char **error_message ATTRIBUTE_UNUSED)
366 bfd_boolean relocatable = (output_bfd != NULL);
368 /* Just call the operation based on the reloc_type. */
369 reloc_stack_operate (reloc_entry->howto->type);
371 if (relocatable)
372 reloc_entry->address += input_section->output_offset;
374 return bfd_reloc_ok;
377 static bfd_reloc_status_type
378 bfin_const_reloc (bfd *abfd ATTRIBUTE_UNUSED,
379 arelent *reloc_entry,
380 asymbol *symbol ATTRIBUTE_UNUSED,
381 PTR data ATTRIBUTE_UNUSED,
382 asection *input_section,
383 bfd *output_bfd,
384 char **error_message ATTRIBUTE_UNUSED)
386 bfd_boolean relocatable = (output_bfd != NULL);
388 /* Push the addend portion of the relocation. */
389 reloc_stack_push (reloc_entry->addend);
391 if (relocatable)
392 reloc_entry->address += input_section->output_offset;
394 return bfd_reloc_ok;
397 static bfd_reloc_status_type
398 bfin_imm16_reloc (bfd *abfd,
399 arelent *reloc_entry,
400 asymbol *symbol,
401 PTR data,
402 asection *input_section,
403 bfd *output_bfd,
404 char **error_message ATTRIBUTE_UNUSED)
406 bfd_vma relocation, x;
407 bfd_size_type reloc_addr = reloc_entry->address;
408 bfd_vma output_base = 0;
409 reloc_howto_type *howto = reloc_entry->howto;
410 asection *output_section;
411 bfd_boolean relocatable = (output_bfd != NULL);
413 /* Is the address of the relocation really within the section? */
414 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
415 return bfd_reloc_outofrange;
417 if (is_reloc_stack_empty ())
419 if (bfd_is_und_section (symbol->section)
420 && (symbol->flags & BSF_WEAK) == 0
421 && !relocatable)
422 return bfd_reloc_undefined;
424 output_section = symbol->section->output_section;
425 relocation = symbol->value;
427 /* Convert input-section-relative symbol value to absolute. */
428 if (relocatable)
429 output_base = 0;
430 else
431 output_base = output_section->vma;
433 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
434 relocation += output_base + symbol->section->output_offset;
436 /* Add in supplied addend. */
437 relocation += reloc_entry->addend;
439 else
441 relocation = reloc_stack_pop ();
444 if (relocatable)
446 reloc_entry->address += input_section->output_offset;
447 reloc_entry->addend += symbol->section->output_offset;
449 else
451 reloc_entry->addend = 0;
454 if (howto->complain_on_overflow != complain_overflow_dont)
456 bfd_reloc_status_type flag;
457 flag = bfd_check_overflow (howto->complain_on_overflow,
458 howto->bitsize,
459 howto->rightshift,
460 bfd_arch_bits_per_address(abfd),
461 relocation);
462 if (flag != bfd_reloc_ok)
463 return flag;
467 /* Here the variable relocation holds the final address of the
468 symbol we are relocating against, plus any addend. */
470 relocation >>= (bfd_vma) howto->rightshift;
471 x = relocation;
472 bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
473 return bfd_reloc_ok;
477 static bfd_reloc_status_type
478 bfin_byte4_reloc (bfd *abfd,
479 arelent *reloc_entry,
480 asymbol *symbol,
481 PTR data,
482 asection *input_section,
483 bfd *output_bfd,
484 char **error_message ATTRIBUTE_UNUSED)
486 bfd_vma relocation, x;
487 bfd_size_type addr = reloc_entry->address;
488 bfd_vma output_base = 0;
489 asection *output_section;
490 bfd_boolean relocatable = (output_bfd != NULL);
492 /* Is the address of the relocation really within the section? */
493 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
494 return bfd_reloc_outofrange;
496 if (is_reloc_stack_empty ())
498 if (bfd_is_und_section (symbol->section)
499 && (symbol->flags & BSF_WEAK) == 0
500 && !relocatable)
501 return bfd_reloc_undefined;
503 output_section = symbol->section->output_section;
504 relocation = symbol->value;
505 /* Convert input-section-relative symbol value to absolute. */
506 if (relocatable)
507 output_base = 0;
508 else
509 output_base = output_section->vma;
511 if ((symbol->name
512 && symbol->section->name
513 && !strcmp (symbol->name, symbol->section->name))
514 || !relocatable)
516 relocation += output_base + symbol->section->output_offset;
519 relocation += reloc_entry->addend;
521 else
523 relocation = reloc_stack_pop();
524 relocation += reloc_entry->addend;
527 if (relocatable)
529 /* This output will be relocatable ... like ld -r. */
530 reloc_entry->address += input_section->output_offset;
531 reloc_entry->addend += symbol->section->output_offset;
533 else
535 reloc_entry->addend = 0;
538 /* Here the variable relocation holds the final address of the
539 symbol we are relocating against, plus any addend. */
540 x = relocation & 0xFFFF0000;
541 x >>=16;
542 bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
544 x = relocation & 0x0000FFFF;
545 bfd_put_16 (abfd, x, (unsigned char *) data + addr);
546 return bfd_reloc_ok;
549 /* bfin_bfd_reloc handles the blackfin arithmetic relocations.
550 Use this instead of bfd_perform_relocation. */
551 static bfd_reloc_status_type
552 bfin_bfd_reloc (bfd *abfd,
553 arelent *reloc_entry,
554 asymbol *symbol,
555 PTR data,
556 asection *input_section,
557 bfd *output_bfd,
558 char **error_message ATTRIBUTE_UNUSED)
560 bfd_vma relocation;
561 bfd_size_type addr = reloc_entry->address;
562 bfd_vma output_base = 0;
563 reloc_howto_type *howto = reloc_entry->howto;
564 asection *output_section;
565 bfd_boolean relocatable = (output_bfd != NULL);
567 /* Is the address of the relocation really within the section? */
568 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
569 return bfd_reloc_outofrange;
571 if (is_reloc_stack_empty())
573 if (bfd_is_und_section (symbol->section)
574 && (symbol->flags & BSF_WEAK) == 0
575 && !relocatable)
576 return bfd_reloc_undefined;
578 /* Get symbol value. (Common symbols are special.) */
579 if (bfd_is_com_section (symbol->section))
580 relocation = 0;
581 else
582 relocation = symbol->value;
584 output_section = symbol->section->output_section;
586 /* Convert input-section-relative symbol value to absolute. */
587 if (relocatable)
588 output_base = 0;
589 else
590 output_base = output_section->vma;
592 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
593 relocation += output_base + symbol->section->output_offset;
595 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
597 /* Add in supplied addend. */
598 relocation += reloc_entry->addend;
602 else
604 relocation = reloc_stack_pop();
607 /* Here the variable relocation holds the final address of the
608 symbol we are relocating against, plus any addend. */
610 if (howto->pc_relative == TRUE)
612 relocation -= input_section->output_section->vma + input_section->output_offset;
614 if (howto->pcrel_offset == TRUE)
615 relocation -= reloc_entry->address;
618 if (relocatable)
620 reloc_entry->address += input_section->output_offset;
621 reloc_entry->addend += symbol->section->output_offset;
624 if (howto->complain_on_overflow != complain_overflow_dont)
626 bfd_reloc_status_type status;
628 status = bfd_check_overflow (howto->complain_on_overflow,
629 howto->bitsize,
630 howto->rightshift,
631 bfd_arch_bits_per_address(abfd),
632 relocation);
633 if (status != bfd_reloc_ok)
634 return status;
637 /* If rightshift is 1 and the number odd, return error. */
638 if (howto->rightshift && (relocation & 0x01))
640 fprintf(stderr, "relocation should be even number\n");
641 return bfd_reloc_overflow;
644 relocation >>= (bfd_vma) howto->rightshift;
646 /* Shift everything up to where it's going to be used. */
648 relocation <<= (bfd_vma) howto->bitpos;
650 #define DOIT(x) \
651 x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
653 /* handle 8 and 16 bit relocations here. */
654 switch (howto->size)
656 case 0:
658 char x = bfd_get_8 (abfd, (char *) data + addr);
659 DOIT (x);
660 bfd_put_8 (abfd, x, (unsigned char *) data + addr);
662 break;
664 case 1:
666 unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
667 DOIT (x);
668 bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
670 break;
672 default:
673 return bfd_reloc_other;
676 return bfd_reloc_ok;
679 #if 0
680 static bfd_reloc_status_type bfin_bfd_reloc
681 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
683 static bfd_reloc_status_type bfin_imm16_reloc
684 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
686 static bfd_reloc_status_type bfin_pcrel24_reloc
687 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
689 static bfd_reloc_status_type bfin_pltpc_reloc
690 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
692 static bfd_reloc_status_type bfin_const_reloc
693 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
695 static bfd_reloc_status_type bfin_oper_reloc
696 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
698 static bfd_reloc_status_type bfin_byte4_reloc
699 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
701 static bfd_reloc_status_type bfin_push_reloc
702 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
704 static bfd_boolean bfin_is_local_label_name
705 PARAMS ((bfd *, const char *));
706 #endif
707 bfd_boolean bfd_bfin_elf32_create_embedded_relocs
708 PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
711 /* HOWTO Table for blackfin.
712 Blackfin relocations are fairly complicated.
713 Some of the salient features are
714 a. Even numbered offsets. A number of (not all) relocations are
715 even numbered. This means that the rightmost bit is not stored.
716 Needs to right shift by 1 and check to see if value is not odd
717 b. A relocation can be an expression. An expression takes on
718 a variety of relocations arranged in a stack.
719 As a result, we cannot use the standard generic function as special
720 function. We will have our own, which is very similar to the standard
721 generic function except that it understands how to get the value from
722 the relocation stack. . */
724 #define BFIN_RELOC_MIN 0
725 #define BFIN_RELOC_MAX 0x13
726 #define BFIN_GNUEXT_RELOC_MIN 0x40
727 #define BFIN_GNUEXT_RELOC_MAX 0x43
728 #define BFIN_ARELOC_MIN 0xE0
729 #define BFIN_ARELOC_MAX 0xF3
731 static reloc_howto_type bfin_howto_table [] =
733 /* This reloc does nothing. . */
734 HOWTO (R_unused0, /* type. */
735 0, /* rightshift. */
736 2, /* size (0 = byte, 1 = short, 2 = long). */
737 32, /* bitsize. */
738 FALSE, /* pc_relative. */
739 0, /* bitpos. */
740 complain_overflow_bitfield, /* complain_on_overflow. */
741 bfd_elf_generic_reloc, /* special_function. */
742 "R_unused0", /* name. */
743 FALSE, /* partial_inplace. */
744 0, /* src_mask. */
745 0, /* dst_mask. */
746 FALSE), /* pcrel_offset. */
748 HOWTO (R_pcrel5m2, /* type. */
749 1, /* rightshift. */
750 1, /* size (0 = byte, 1 = short, 2 = long).. */
751 4, /* bitsize. */
752 TRUE, /* pc_relative. */
753 0, /* bitpos. */
754 complain_overflow_unsigned, /* complain_on_overflow. */
755 bfin_bfd_reloc, /* special_function. */
756 "R_pcrel5m2", /* name. */
757 FALSE, /* partial_inplace. */
758 0, /* src_mask. */
759 0x0000000F, /* dst_mask. */
760 FALSE), /* pcrel_offset. */
762 HOWTO (R_unused1, /* type. */
763 0, /* rightshift. */
764 2, /* size (0 = byte, 1 = short, 2 = long). */
765 32, /* bitsize. */
766 FALSE, /* pc_relative. */
767 0, /* bitpos. */
768 complain_overflow_bitfield, /* complain_on_overflow. */
769 bfd_elf_generic_reloc, /* special_function. */
770 "R_unused1", /* name. */
771 FALSE, /* partial_inplace. */
772 0, /* src_mask. */
773 0, /* dst_mask. */
774 FALSE), /* pcrel_offset. */
776 HOWTO (R_pcrel10, /* type. */
777 1, /* rightshift. */
778 1, /* size (0 = byte, 1 = short, 2 = long). */
779 10, /* bitsize. */
780 TRUE, /* pc_relative. */
781 0, /* bitpos. */
782 complain_overflow_signed, /* complain_on_overflow. */
783 bfin_bfd_reloc, /* special_function. */
784 "R_pcrel10", /* name. */
785 FALSE, /* partial_inplace. */
786 0, /* src_mask. */
787 0x000003FF, /* dst_mask. */
788 TRUE), /* pcrel_offset. */
790 HOWTO (R_pcrel12_jump, /* type. */
791 1, /* rightshift. */
792 /* the offset is actually 13 bit
793 aligned on a word boundary so
794 only 12 bits have to be used.
795 Right shift the rightmost bit.. */
796 1, /* size (0 = byte, 1 = short, 2 = long). */
797 12, /* bitsize. */
798 TRUE, /* pc_relative. */
799 0, /* bitpos. */
800 complain_overflow_signed, /* complain_on_overflow. */
801 bfin_bfd_reloc, /* special_function. */
802 "R_pcrel12_jump", /* name. */
803 FALSE, /* partial_inplace. */
804 0, /* src_mask. */
805 0x0FFF, /* dst_mask. */
806 TRUE), /* pcrel_offset. */
808 HOWTO (R_rimm16, /* type. */
809 0, /* rightshift. */
810 1, /* size (0 = byte, 1 = short, 2 = long). */
811 16, /* bitsize. */
812 FALSE, /* pc_relative. */
813 0, /* bitpos. */
814 complain_overflow_signed, /* complain_on_overflow. */
815 bfin_imm16_reloc, /* special_function. */
816 "R_rimm16", /* name. */
817 FALSE, /* partial_inplace. */
818 0, /* src_mask. */
819 0x0000FFFF, /* dst_mask. */
820 TRUE), /* pcrel_offset. */
822 HOWTO (R_luimm16, /* type. */
823 0, /* rightshift. */
824 1, /* size (0 = byte, 1 = short, 2 = long). */
825 16, /* bitsize. */
826 FALSE, /* pc_relative. */
827 0, /* bitpos. */
828 complain_overflow_dont, /* complain_on_overflow. */
829 bfin_imm16_reloc, /* special_function. */
830 "R_luimm16", /* name. */
831 FALSE, /* partial_inplace. */
832 0, /* src_mask. */
833 0x0000FFFF, /* dst_mask. */
834 TRUE), /* pcrel_offset. */
836 HOWTO (R_huimm16, /* type. */
837 16, /* rightshift. */
838 1, /* size (0 = byte, 1 = short, 2 = long). */
839 16, /* bitsize. */
840 FALSE, /* pc_relative. */
841 0, /* bitpos. */
842 complain_overflow_unsigned, /* complain_on_overflow. */
843 bfin_imm16_reloc, /* special_function. */
844 "R_huimm16", /* name. */
845 FALSE, /* partial_inplace. */
846 0, /* src_mask. */
847 0x0000FFFF, /* dst_mask. */
848 TRUE), /* pcrel_offset. */
850 HOWTO (R_pcrel12_jump_s, /* type. */
851 1, /* rightshift. */
852 1, /* size (0 = byte, 1 = short, 2 = long). */
853 12, /* bitsize. */
854 TRUE, /* pc_relative. */
855 0, /* bitpos. */
856 complain_overflow_signed, /* complain_on_overflow. */
857 bfin_bfd_reloc, /* special_function. */
858 "R_pcrel12_jump_s", /* name. */
859 FALSE, /* partial_inplace. */
860 0, /* src_mask. */
861 0x00000FFF, /* dst_mask. */
862 TRUE), /* pcrel_offset. */
864 HOWTO (R_pcrel24_jump_x, /* type. */
865 1, /* rightshift. */
866 2, /* size (0 = byte, 1 = short, 2 = long). */
867 24, /* bitsize. */
868 TRUE, /* pc_relative. */
869 0, /* bitpos. */
870 complain_overflow_signed, /* complain_on_overflow. */
871 bfin_pcrel24_reloc, /* special_function. */
872 "R_pcrel24_jump_x", /* name. */
873 FALSE, /* partial_inplace. */
874 0, /* src_mask. */
875 0x00FFFFFF, /* dst_mask. */
876 TRUE), /* pcrel_offset. */
878 HOWTO (R_pcrel24, /* type. */
879 1, /* rightshift. */
880 2, /* size (0 = byte, 1 = short, 2 = long). */
881 24, /* bitsize. */
882 TRUE, /* pc_relative. */
883 0, /* bitpos. */
884 complain_overflow_signed, /* complain_on_overflow. */
885 bfin_pcrel24_reloc, /* special_function. */
886 "R_pcrel24", /* name. */
887 FALSE, /* partial_inplace. */
888 0, /* src_mask. */
889 0x00FFFFFF, /* dst_mask. */
890 TRUE), /* pcrel_offset. */
892 HOWTO (R_unusedb, /* type. */
893 0, /* rightshift. */
894 2, /* size (0 = byte, 1 = short, 2 = long). */
895 32, /* bitsize. */
896 FALSE, /* pc_relative. */
897 0, /* bitpos. */
898 complain_overflow_dont, /* complain_on_overflow. */
899 bfd_elf_generic_reloc, /* special_function. */
900 "R_unusedb", /* name. */
901 FALSE, /* partial_inplace. */
902 0, /* src_mask. */
903 0, /* dst_mask. */
904 FALSE), /* pcrel_offset. */
906 HOWTO (R_unusedc, /* type. */
907 0, /* rightshift. */
908 2, /* size (0 = byte, 1 = short, 2 = long). */
909 32, /* bitsize. */
910 FALSE, /* pc_relative. */
911 0, /* bitpos. */
912 complain_overflow_dont, /* complain_on_overflow. */
913 bfd_elf_generic_reloc, /* special_function. */
914 "R_unusedc", /* name. */
915 FALSE, /* partial_inplace. */
916 0, /* src_mask. */
917 0, /* dst_mask. */
918 FALSE), /* pcrel_offset. */
920 HOWTO (R_pcrel24_jump_l, /* type. */
921 1, /* rightshift. */
922 2, /* size (0 = byte, 1 = short, 2 = long). */
923 24, /* bitsize. */
924 TRUE, /* pc_relative. */
925 0, /* bitpos. */
926 complain_overflow_signed, /* complain_on_overflow. */
927 bfin_pcrel24_reloc, /* special_function. */
928 "R_pcrel24_jump_l", /* name. */
929 FALSE, /* partial_inplace. */
930 0, /* src_mask. */
931 0x00FFFFFF, /* dst_mask. */
932 TRUE), /* pcrel_offset. */
934 HOWTO (R_pcrel24_call_x, /* type. */
935 1, /* rightshift. */
936 2, /* size (0 = byte, 1 = short, 2 = long). */
937 24, /* bitsize. */
938 TRUE, /* pc_relative. */
939 0, /* bitpos. */
940 complain_overflow_signed, /* complain_on_overflow. */
941 bfin_pcrel24_reloc, /* special_function. */
942 "R_pcrel24_call_x", /* name. */
943 FALSE, /* partial_inplace. */
944 0, /* src_mask. */
945 0x00FFFFFF, /* dst_mask. */
946 TRUE), /* pcrel_offset. */
948 HOWTO (R_var_eq_symb, /* type. */
949 0, /* rightshift. */
950 2, /* size (0 = byte, 1 = short, 2 = long). */
951 32, /* bitsize. */
952 FALSE, /* pc_relative. */
953 0, /* bitpos. */
954 complain_overflow_bitfield, /* complain_on_overflow. */
955 bfin_bfd_reloc, /* special_function. */
956 "R_var_eq_symb", /* name. */
957 FALSE, /* partial_inplace. */
958 0, /* src_mask. */
959 0, /* dst_mask. */
960 FALSE), /* pcrel_offset. */
962 HOWTO (R_byte_data, /* type. */
963 0, /* rightshift. */
964 0, /* size (0 = byte, 1 = short, 2 = long). */
965 8, /* bitsize. */
966 FALSE, /* pc_relative. */
967 0, /* bitpos. */
968 complain_overflow_unsigned, /* complain_on_overflow. */
969 bfin_bfd_reloc, /* special_function. */
970 "R_byte_data", /* name. */
971 FALSE, /* partial_inplace. */
972 0, /* src_mask. */
973 0xFF, /* dst_mask. */
974 TRUE), /* pcrel_offset. */
976 HOWTO (R_byte2_data, /* type. */
977 0, /* rightshift. */
978 1, /* size (0 = byte, 1 = short, 2 = long). */
979 16, /* bitsize. */
980 FALSE, /* pc_relative. */
981 0, /* bitpos. */
982 complain_overflow_signed, /* complain_on_overflow. */
983 bfin_bfd_reloc, /* special_function. */
984 "R_byte2_data", /* name. */
985 FALSE, /* partial_inplace. */
986 0, /* src_mask. */
987 0xFFFF, /* dst_mask. */
988 TRUE), /* pcrel_offset. */
990 HOWTO (R_byte4_data, /* type. */
991 0, /* rightshift. */
992 2, /* size (0 = byte, 1 = short, 2 = long). */
993 32, /* bitsize. */
994 FALSE, /* pc_relative. */
995 0, /* bitpos. */
996 complain_overflow_unsigned, /* complain_on_overflow. */
997 bfin_byte4_reloc, /* special_function. */
998 "R_byte4_data", /* name. */
999 FALSE, /* partial_inplace. */
1000 0, /* src_mask. */
1001 0xFFFFFFFF, /* dst_mask. */
1002 TRUE), /* pcrel_offset. */
1004 HOWTO (R_pcrel11, /* type. */
1005 1, /* rightshift. */
1006 1, /* size (0 = byte, 1 = short, 2 = long). */
1007 10, /* bitsize. */
1008 TRUE, /* pc_relative. */
1009 0, /* bitpos. */
1010 complain_overflow_unsigned, /* complain_on_overflow. */
1011 bfin_bfd_reloc, /* special_function. */
1012 "R_pcrel11", /* name. */
1013 FALSE, /* partial_inplace. */
1014 0, /* src_mask. */
1015 0x000003FF, /* dst_mask. */
1016 FALSE), /* pcrel_offset. */
1019 static reloc_howto_type bfin_areloc_howto_table [] =
1021 HOWTO (R_push,
1025 FALSE,
1027 complain_overflow_dont,
1028 bfin_push_reloc,
1029 "R_expst_push",
1030 FALSE,
1033 FALSE),
1035 HOWTO (R_const,
1039 FALSE,
1041 complain_overflow_dont,
1042 bfin_const_reloc,
1043 "R_expst_const",
1044 FALSE,
1047 FALSE),
1049 HOWTO (R_add,
1053 FALSE,
1055 complain_overflow_dont,
1056 bfin_oper_reloc,
1057 "R_expst_add",
1058 FALSE,
1061 FALSE),
1063 HOWTO (R_sub,
1067 FALSE,
1069 complain_overflow_dont,
1070 bfin_oper_reloc,
1071 "R_expst_sub",
1072 FALSE,
1075 FALSE),
1077 HOWTO (R_mult,
1081 FALSE,
1083 complain_overflow_dont,
1084 bfin_oper_reloc,
1085 "R_expst_mult",
1086 FALSE,
1089 FALSE),
1091 HOWTO (R_div, /* type. */
1092 0, /* rightshift. */
1093 0, /* size (0 = byte, 1 = short, 2 = long). */
1094 0, /* bitsize. */
1095 FALSE, /* pc_relative. */
1096 0, /* bitpos. */
1097 complain_overflow_dont, /* complain_on_overflow. */
1098 bfin_oper_reloc, /* special_function. */
1099 "R_expst_div", /* name. */
1100 FALSE, /* partial_inplace. */
1101 0, /* src_mask. */
1102 0, /* dst_mask. */
1103 FALSE), /* pcrel_offset. */
1105 HOWTO (R_mod, /* type. */
1106 0, /* rightshift. */
1107 0, /* size (0 = byte, 1 = short, 2 = long). */
1108 0, /* bitsize. */
1109 FALSE, /* pc_relative. */
1110 0, /* bitpos. */
1111 complain_overflow_dont, /* complain_on_overflow. */
1112 bfin_oper_reloc, /* special_function. */
1113 "R_expst_mod", /* name. */
1114 FALSE, /* partial_inplace. */
1115 0, /* src_mask. */
1116 0, /* dst_mask. */
1117 FALSE), /* pcrel_offset. */
1119 HOWTO (R_lshift, /* type. */
1120 0, /* rightshift. */
1121 0, /* size (0 = byte, 1 = short, 2 = long). */
1122 0, /* bitsize. */
1123 FALSE, /* pc_relative. */
1124 0, /* bitpos. */
1125 complain_overflow_dont, /* complain_on_overflow. */
1126 bfin_oper_reloc, /* special_function. */
1127 "R_expst_lshift", /* name. */
1128 FALSE, /* partial_inplace. */
1129 0, /* src_mask. */
1130 0, /* dst_mask. */
1131 FALSE), /* pcrel_offset. */
1133 HOWTO (R_rshift, /* type. */
1134 0, /* rightshift. */
1135 0, /* size (0 = byte, 1 = short, 2 = long). */
1136 0, /* bitsize. */
1137 FALSE, /* pc_relative. */
1138 0, /* bitpos. */
1139 complain_overflow_dont, /* complain_on_overflow. */
1140 bfin_oper_reloc, /* special_function. */
1141 "R_expst_rshift", /* name. */
1142 FALSE, /* partial_inplace. */
1143 0, /* src_mask. */
1144 0, /* dst_mask. */
1145 FALSE), /* pcrel_offset. */
1147 HOWTO (R_and, /* type. */
1148 0, /* rightshift. */
1149 0, /* size (0 = byte, 1 = short, 2 = long). */
1150 0, /* bitsize. */
1151 FALSE, /* pc_relative. */
1152 0, /* bitpos. */
1153 complain_overflow_dont, /* complain_on_overflow. */
1154 bfin_oper_reloc, /* special_function. */
1155 "R_expst_and", /* name. */
1156 FALSE, /* partial_inplace. */
1157 0, /* src_mask. */
1158 0, /* dst_mask. */
1159 FALSE), /* pcrel_offset. */
1161 HOWTO (R_or, /* type. */
1162 0, /* rightshift. */
1163 0, /* size (0 = byte, 1 = short, 2 = long). */
1164 0, /* bitsize. */
1165 FALSE, /* pc_relative. */
1166 0, /* bitpos. */
1167 complain_overflow_dont, /* complain_on_overflow. */
1168 bfin_oper_reloc, /* special_function. */
1169 "R_expst_or", /* name. */
1170 FALSE, /* partial_inplace. */
1171 0, /* src_mask. */
1172 0, /* dst_mask. */
1173 FALSE), /* pcrel_offset. */
1175 HOWTO (R_xor, /* type. */
1176 0, /* rightshift. */
1177 0, /* size (0 = byte, 1 = short, 2 = long). */
1178 0, /* bitsize. */
1179 FALSE, /* pc_relative. */
1180 0, /* bitpos. */
1181 complain_overflow_dont, /* complain_on_overflow. */
1182 bfin_oper_reloc, /* special_function. */
1183 "R_expst_xor", /* name. */
1184 FALSE, /* partial_inplace. */
1185 0, /* src_mask. */
1186 0, /* dst_mask. */
1187 FALSE), /* pcrel_offset. */
1189 HOWTO (R_land, /* type. */
1190 0, /* rightshift. */
1191 0, /* size (0 = byte, 1 = short, 2 = long). */
1192 0, /* bitsize. */
1193 FALSE, /* pc_relative. */
1194 0, /* bitpos. */
1195 complain_overflow_dont, /* complain_on_overflow. */
1196 bfin_oper_reloc, /* special_function. */
1197 "R_expst_land", /* name. */
1198 FALSE, /* partial_inplace. */
1199 0, /* src_mask. */
1200 0, /* dst_mask. */
1201 FALSE), /* pcrel_offset. */
1203 HOWTO (R_lor, /* type. */
1204 0, /* rightshift. */
1205 0, /* size (0 = byte, 1 = short, 2 = long). */
1206 0, /* bitsize. */
1207 FALSE, /* pc_relative. */
1208 0, /* bitpos. */
1209 complain_overflow_dont, /* complain_on_overflow. */
1210 bfin_oper_reloc, /* special_function. */
1211 "R_expst_lor", /* name. */
1212 FALSE, /* partial_inplace. */
1213 0, /* src_mask. */
1214 0, /* dst_mask. */
1215 FALSE), /* pcrel_offset. */
1217 HOWTO (R_len, /* type. */
1218 0, /* rightshift. */
1219 0, /* size (0 = byte, 1 = short, 2 = long). */
1220 0, /* bitsize. */
1221 FALSE, /* pc_relative. */
1222 0, /* bitpos. */
1223 complain_overflow_dont, /* complain_on_overflow. */
1224 bfin_oper_reloc, /* special_function. */
1225 "R_expst_len", /* name. */
1226 FALSE, /* partial_inplace. */
1227 0, /* src_mask. */
1228 0, /* dst_mask. */
1229 FALSE), /* pcrel_offset. */
1231 HOWTO (R_neg, /* type. */
1232 0, /* rightshift. */
1233 0, /* size (0 = byte, 1 = short, 2 = long). */
1234 0, /* bitsize. */
1235 FALSE, /* pc_relative. */
1236 0, /* bitpos. */
1237 complain_overflow_dont, /* complain_on_overflow. */
1238 bfin_oper_reloc, /* special_function. */
1239 "R_expst_neg", /* name. */
1240 FALSE, /* partial_inplace. */
1241 0, /* src_mask. */
1242 0, /* dst_mask. */
1243 FALSE), /* pcrel_offset. */
1245 HOWTO (R_comp, /* type. */
1246 0, /* rightshift. */
1247 0, /* size (0 = byte, 1 = short, 2 = long). */
1248 0, /* bitsize. */
1249 FALSE, /* pc_relative. */
1250 0, /* bitpos. */
1251 complain_overflow_dont, /* complain_on_overflow. */
1252 bfin_oper_reloc, /* special_function. */
1253 "R_expst_comp", /* name. */
1254 FALSE, /* partial_inplace. */
1255 0, /* src_mask. */
1256 0, /* dst_mask. */
1257 FALSE), /* pcrel_offset. */
1259 HOWTO (R_page, /* type. */
1260 0, /* rightshift. */
1261 0, /* size (0 = byte, 1 = short, 2 = long). */
1262 0, /* bitsize. */
1263 FALSE, /* pc_relative. */
1264 0, /* bitpos. */
1265 complain_overflow_dont, /* complain_on_overflow. */
1266 bfin_oper_reloc, /* special_function. */
1267 "R_expst_page", /* name. */
1268 FALSE, /* partial_inplace. */
1269 0, /* src_mask. */
1270 0, /* dst_mask. */
1271 FALSE), /* pcrel_offset. */
1273 HOWTO (R_hwpage, /* type. */
1274 0, /* rightshift. */
1275 0, /* size (0 = byte, 1 = short, 2 = long). */
1276 0, /* bitsize. */
1277 FALSE, /* pc_relative. */
1278 0, /* bitpos. */
1279 complain_overflow_dont, /* complain_on_overflow. */
1280 bfin_oper_reloc, /* special_function. */
1281 "R_expst_hwpage", /* name. */
1282 FALSE, /* partial_inplace. */
1283 0, /* src_mask. */
1284 0, /* dst_mask. */
1285 FALSE), /* pcrel_offset. */
1287 HOWTO (R_addr, /* type. */
1288 0, /* rightshift. */
1289 0, /* size (0 = byte, 1 = short, 2 = long). */
1290 0, /* bitsize. */
1291 FALSE, /* pc_relative. */
1292 0, /* bitpos. */
1293 complain_overflow_dont, /* complain_on_overflow. */
1294 bfin_oper_reloc, /* special_function. */
1295 "R_expst_addr", /* name. */
1296 FALSE, /* partial_inplace. */
1297 0, /* src_mask. */
1298 0, /* dst_mask. */
1299 FALSE), /* pcrel_offset. */
1302 static reloc_howto_type bfin_gnuext_howto_table [] =
1304 HOWTO (R_pltpc, /* type. */
1305 0, /* rightshift. */
1306 1, /* size (0 = byte, 1 = short, 2 = long). */
1307 16, /* bitsize. */
1308 FALSE, /* pc_relative. */
1309 0, /* bitpos. */
1310 complain_overflow_bitfield, /* complain_on_overflow. */
1311 bfin_pltpc_reloc, /* special_function. */
1312 "R_pltpc", /* name. */
1313 FALSE, /* partial_inplace. */
1314 0xffff, /* src_mask. */
1315 0xffff, /* dst_mask. */
1316 FALSE), /* pcrel_offset. */
1318 HOWTO (R_got, /* type. */
1319 0, /* rightshift. */
1320 1, /* size (0 = byte, 1 = short, 2 = long). */
1321 16, /* bitsize. */
1322 FALSE, /* pc_relative. */
1323 0, /* bitpos. */
1324 complain_overflow_bitfield, /* complain_on_overflow. */
1325 bfd_elf_generic_reloc, /* special_function. */
1326 "R_got", /* name. */
1327 FALSE, /* partial_inplace. */
1328 0x7fff, /* src_mask. */
1329 0x7fff, /* dst_mask. */
1330 FALSE), /* pcrel_offset. */
1332 /* GNU extension to record C++ vtable hierarchy. */
1333 HOWTO (R_BFIN_GNU_VTINHERIT, /* type. */
1334 0, /* rightshift. */
1335 2, /* size (0 = byte, 1 = short, 2 = long). */
1336 0, /* bitsize. */
1337 FALSE, /* pc_relative. */
1338 0, /* bitpos. */
1339 complain_overflow_dont, /* complain_on_overflow. */
1340 NULL, /* special_function. */
1341 "R_BFIN_GNU_VTINHERIT", /* name. */
1342 FALSE, /* partial_inplace. */
1343 0, /* src_mask. */
1344 0, /* dst_mask. */
1345 FALSE), /* pcrel_offset. */
1347 /* GNU extension to record C++ vtable member usage. */
1348 HOWTO (R_BFIN_GNU_VTENTRY, /* type. */
1349 0, /* rightshift. */
1350 2, /* size (0 = byte, 1 = short, 2 = long). */
1351 0, /* bitsize. */
1352 FALSE, /* pc_relative. */
1353 0, /* bitpos. */
1354 complain_overflow_dont, /* complain_on_overflow. */
1355 _bfd_elf_rel_vtable_reloc_fn, /* special_function. */
1356 "R_BFIN_GNU_VTENTRY", /* name. */
1357 FALSE, /* partial_inplace. */
1358 0, /* src_mask. */
1359 0, /* dst_mask. */
1360 FALSE) /* pcrel_offset. */
1363 struct bfin_reloc_map
1365 bfd_reloc_code_real_type bfd_reloc_val;
1366 unsigned int bfin_reloc_val;
1369 static const struct bfin_reloc_map bfin_reloc_map [] =
1371 { BFD_RELOC_NONE, R_unused0 },
1372 { BFD_RELOC_BFIN_5_PCREL, R_pcrel5m2 },
1373 { BFD_RELOC_NONE, R_unused1 },
1374 { BFD_RELOC_BFIN_10_PCREL, R_pcrel10 },
1375 { BFD_RELOC_BFIN_12_PCREL_JUMP, R_pcrel12_jump },
1376 { BFD_RELOC_BFIN_16_IMM, R_rimm16 },
1377 { BFD_RELOC_BFIN_16_LOW, R_luimm16 },
1378 { BFD_RELOC_BFIN_16_HIGH, R_huimm16 },
1379 { BFD_RELOC_BFIN_12_PCREL_JUMP_S, R_pcrel12_jump_s },
1380 { BFD_RELOC_24_PCREL, R_pcrel24 },
1381 { BFD_RELOC_24_PCREL, R_pcrel24 },
1382 { BFD_RELOC_BFIN_24_PCREL_JUMP_L, R_pcrel24_jump_l },
1383 { BFD_RELOC_NONE, R_unusedb },
1384 { BFD_RELOC_NONE, R_unusedc },
1385 { BFD_RELOC_BFIN_24_PCREL_CALL_X, R_pcrel24_call_x },
1386 { BFD_RELOC_8, R_byte_data },
1387 { BFD_RELOC_16, R_byte2_data },
1388 { BFD_RELOC_32, R_byte4_data },
1389 { BFD_RELOC_BFIN_11_PCREL, R_pcrel11 },
1390 { BFD_RELOC_BFIN_GOT, R_got },
1391 { BFD_RELOC_BFIN_PLTPC, R_pltpc },
1392 { BFD_RELOC_VTABLE_INHERIT, R_BFIN_GNU_VTINHERIT },
1393 { BFD_RELOC_VTABLE_ENTRY, R_BFIN_GNU_VTENTRY },
1394 { BFD_ARELOC_BFIN_PUSH, R_push },
1395 { BFD_ARELOC_BFIN_CONST, R_const },
1396 { BFD_ARELOC_BFIN_ADD, R_add },
1397 { BFD_ARELOC_BFIN_SUB, R_sub },
1398 { BFD_ARELOC_BFIN_MULT, R_mult },
1399 { BFD_ARELOC_BFIN_DIV, R_div },
1400 { BFD_ARELOC_BFIN_MOD, R_mod },
1401 { BFD_ARELOC_BFIN_LSHIFT, R_lshift },
1402 { BFD_ARELOC_BFIN_RSHIFT, R_rshift },
1403 { BFD_ARELOC_BFIN_AND, R_and },
1404 { BFD_ARELOC_BFIN_OR, R_or },
1405 { BFD_ARELOC_BFIN_XOR, R_xor },
1406 { BFD_ARELOC_BFIN_LAND, R_land },
1407 { BFD_ARELOC_BFIN_LOR, R_lor },
1408 { BFD_ARELOC_BFIN_LEN, R_len },
1409 { BFD_ARELOC_BFIN_NEG, R_neg },
1410 { BFD_ARELOC_BFIN_COMP, R_comp },
1411 { BFD_ARELOC_BFIN_PAGE, R_page },
1412 { BFD_ARELOC_BFIN_HWPAGE, R_hwpage },
1413 { BFD_ARELOC_BFIN_ADDR, R_addr }
1418 static void
1419 bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
1420 arelent *cache_ptr,
1421 Elf_Internal_Rela *dst)
1423 unsigned int r_type;
1425 r_type = ELF32_R_TYPE (dst->r_info);
1427 if (r_type <= BFIN_RELOC_MAX)
1428 cache_ptr->howto = &bfin_howto_table [r_type];
1430 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1431 cache_ptr->howto = &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1433 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1434 cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1436 else
1437 cache_ptr->howto = (reloc_howto_type *) NULL;
1440 /* Given a BFD reloc type, return the howto. */
1441 static reloc_howto_type *
1442 bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1443 bfd_reloc_code_real_type code)
1445 unsigned int i;
1446 unsigned int r_type = BFIN_RELOC_MIN;
1448 for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
1449 if (bfin_reloc_map[i].bfd_reloc_val == code)
1450 r_type = bfin_reloc_map[i].bfin_reloc_val;
1452 if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
1453 return &bfin_howto_table [r_type];
1455 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1456 return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1458 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1459 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1461 return (reloc_howto_type *) NULL;
1464 /* Given a bfin relocation type, return the howto. */
1465 static reloc_howto_type *
1466 bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1467 unsigned int r_type)
1469 if (r_type <= BFIN_RELOC_MAX)
1470 return &bfin_howto_table [r_type];
1472 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1473 return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1475 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1476 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1478 return (reloc_howto_type *) NULL;
1482 /* Return TRUE if the name is a local label.
1483 bfin local labels begin with L$. */
1484 static bfd_boolean
1485 bfin_is_local_label_name (
1486 bfd *abfd ATTRIBUTE_UNUSED,
1487 const char *label)
1489 if (label[0] == 'L' && label[1] == '$' )
1490 return TRUE;
1492 return _bfd_elf_is_local_label_name (abfd, label);
1496 /* Look through the relocs for a section during the first phase, and
1497 allocate space in the global offset table or procedure linkage
1498 table. */
1500 static bfd_boolean
1501 bfin_check_relocs (bfd * abfd,
1502 struct bfd_link_info *info,
1503 asection *sec,
1504 const Elf_Internal_Rela *relocs)
1506 bfd *dynobj;
1507 Elf_Internal_Shdr *symtab_hdr;
1508 struct elf_link_hash_entry **sym_hashes;
1509 bfd_signed_vma *local_got_refcounts;
1510 const Elf_Internal_Rela *rel;
1511 const Elf_Internal_Rela *rel_end;
1512 asection *sgot;
1513 asection *srelgot;
1514 asection *sreloc;
1515 if (info->relocatable)
1516 return TRUE;
1518 dynobj = elf_hash_table (info)->dynobj;
1519 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1520 sym_hashes = elf_sym_hashes (abfd);
1521 local_got_refcounts = elf_local_got_refcounts (abfd);
1523 sgot = NULL;
1524 srelgot = NULL;
1525 sreloc = NULL;
1527 rel_end = relocs + sec->reloc_count;
1528 for (rel = relocs; rel < rel_end; rel++)
1530 unsigned long r_symndx;
1531 struct elf_link_hash_entry *h;
1533 r_symndx = ELF32_R_SYM (rel->r_info);
1534 if (r_symndx < symtab_hdr->sh_info)
1535 h = NULL;
1536 else
1537 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1539 switch (ELF32_R_TYPE (rel->r_info))
1541 /* This relocation describes the C++ object vtable hierarchy.
1542 Reconstruct it for later use during GC. */
1543 case R_BFIN_GNU_VTINHERIT:
1544 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1545 return FALSE;
1546 break;
1548 /* This relocation describes which C++ vtable entries
1549 are actually used. Record for later use during GC. */
1550 case R_BFIN_GNU_VTENTRY:
1551 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1552 return FALSE;
1553 break;
1555 case R_got:
1556 if (h != NULL
1557 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1558 break;
1559 /* Fall through. */
1561 if (dynobj == NULL)
1563 /* Create the .got section. */
1564 elf_hash_table (info)->dynobj = dynobj = abfd;
1565 if (!_bfd_elf_create_got_section (dynobj, info))
1566 return FALSE;
1569 if (sgot == NULL)
1571 sgot = bfd_get_section_by_name (dynobj, ".got");
1572 BFD_ASSERT (sgot != NULL);
1575 if (srelgot == NULL && (h != NULL || info->shared))
1577 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1578 if (srelgot == NULL)
1580 srelgot = bfd_make_section (dynobj, ".rela.got");
1581 if (srelgot == NULL
1582 || !bfd_set_section_flags (dynobj, srelgot,
1583 (SEC_ALLOC
1584 | SEC_LOAD
1585 | SEC_HAS_CONTENTS
1586 | SEC_IN_MEMORY
1587 | SEC_LINKER_CREATED
1588 | SEC_READONLY))
1589 || !bfd_set_section_alignment (dynobj, srelgot, 2))
1590 return FALSE;
1594 if (h != NULL)
1596 if (h->got.refcount == 0)
1598 /* Make sure this symbol is output as a dynamic symbol. */
1599 if (h->dynindx == -1 && !h->forced_local)
1601 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1602 return FALSE;
1605 /* Allocate space in the .got section. */
1606 sgot->size += 4;
1607 /* Allocate relocation space. */
1608 srelgot->size += sizeof (Elf32_External_Rela);
1610 h->got.refcount++;
1612 else
1614 /* This is a global offset table entry for a local symbol. */
1615 if (local_got_refcounts == NULL)
1617 bfd_size_type size;
1619 size = symtab_hdr->sh_info;
1620 size *= sizeof (bfd_signed_vma);
1621 local_got_refcounts = ((bfd_signed_vma *)
1622 bfd_zalloc (abfd, size));
1623 if (local_got_refcounts == NULL)
1624 return FALSE;
1625 elf_local_got_refcounts (abfd) = local_got_refcounts;
1627 if (local_got_refcounts[r_symndx] == 0)
1629 sgot->size += 4;
1630 if (info->shared)
1632 /* If we are generating a shared object, we need to
1633 output a R_68K_RELATIVE reloc so that the dynamic
1634 linker can adjust this GOT entry. */
1635 srelgot->size += sizeof (Elf32_External_Rela);
1638 local_got_refcounts[r_symndx]++;
1640 break;
1642 default:
1643 break;
1647 return TRUE;
1650 static enum elf_reloc_type_class
1651 elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
1653 switch ((int) ELF32_R_TYPE (rela->r_info))
1655 default:
1656 return reloc_class_normal;
1660 static bfd_boolean
1661 bfin_relocate_section (bfd * output_bfd,
1662 struct bfd_link_info *info,
1663 bfd * input_bfd,
1664 asection * input_section,
1665 bfd_byte * contents,
1666 Elf_Internal_Rela * relocs,
1667 Elf_Internal_Sym * local_syms,
1668 asection ** local_sections)
1670 bfd *dynobj;
1671 Elf_Internal_Shdr *symtab_hdr;
1672 struct elf_link_hash_entry **sym_hashes;
1673 bfd_vma *local_got_offsets;
1674 asection *sgot;
1675 asection *sreloc;
1676 Elf_Internal_Rela *rel;
1677 Elf_Internal_Rela *relend;
1678 int i = 0;
1680 if (info->relocatable)
1681 return TRUE;
1683 dynobj = elf_hash_table (info)->dynobj;
1684 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1685 sym_hashes = elf_sym_hashes (input_bfd);
1686 local_got_offsets = elf_local_got_offsets (input_bfd);
1688 sgot = NULL;
1689 sreloc = NULL;
1691 rel = relocs;
1692 relend = relocs + input_section->reloc_count;
1693 for (; rel < relend; rel++, i++)
1695 int r_type;
1696 reloc_howto_type *howto;
1697 unsigned long r_symndx;
1698 struct elf_link_hash_entry *h;
1699 Elf_Internal_Sym *sym;
1700 asection *sec;
1701 bfd_vma relocation = 0;
1702 bfd_boolean unresolved_reloc;
1703 bfd_reloc_status_type r;
1704 bfd_vma address;
1706 r_type = ELF32_R_TYPE (rel->r_info);
1707 if (r_type < 0 || r_type >= 243)
1709 bfd_set_error (bfd_error_bad_value);
1710 return FALSE;
1713 if (r_type == R_BFIN_GNU_VTENTRY
1714 || r_type == R_BFIN_GNU_VTINHERIT)
1715 continue;
1717 howto = bfin_reloc_type_lookup (input_bfd, r_type);
1718 if (howto == NULL)
1720 bfd_set_error (bfd_error_bad_value);
1721 return FALSE;
1723 r_symndx = ELF32_R_SYM (rel->r_info);
1725 h = NULL;
1726 sym = NULL;
1727 sec = NULL;
1728 unresolved_reloc = FALSE;
1730 if (r_symndx < symtab_hdr->sh_info)
1732 sym = local_syms + r_symndx;
1733 sec = local_sections[r_symndx];
1734 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1736 else
1738 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1740 while (h->root.type == bfd_link_hash_indirect
1741 || h->root.type == bfd_link_hash_warning)
1742 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1744 if (!
1745 (!strcmp (h->root.root.string, ".__constant")
1746 || !strcmp (h->root.root.string, ".__operator")))
1748 bfd_boolean warned;
1749 h = NULL;
1750 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1751 r_symndx, symtab_hdr, sym_hashes,
1752 h, sec, relocation,
1753 unresolved_reloc, warned);
1758 address = rel->r_offset;
1759 /* First, get stack relocs out of the way. */
1760 switch (r_type)
1762 case R_push:
1763 reloc_stack_push (relocation + rel->r_addend);
1764 r = bfd_reloc_ok;
1765 goto done_reloc;
1766 case R_const:
1767 reloc_stack_push (rel->r_addend);
1768 r = bfd_reloc_ok;
1769 goto done_reloc;
1770 case R_add:
1771 case R_sub:
1772 case R_mult:
1773 case R_div:
1774 case R_mod:
1775 case R_lshift:
1776 case R_rshift:
1777 case R_neg:
1778 case R_and:
1779 case R_or:
1780 case R_xor:
1781 case R_land:
1782 case R_lor:
1783 case R_comp:
1784 case R_page:
1785 case R_hwpage:
1786 reloc_stack_operate (r_type);
1787 r = bfd_reloc_ok;
1788 goto done_reloc;
1790 default:
1791 if (!is_reloc_stack_empty())
1792 relocation = reloc_stack_pop ();
1793 break;
1796 /* Then, process normally. */
1797 switch (r_type)
1799 case R_BFIN_GNU_VTINHERIT:
1800 case R_BFIN_GNU_VTENTRY:
1801 return bfd_reloc_ok;
1803 case R_got:
1804 /* Relocation is to the address of the entry for this symbol
1805 in the global offset table. */
1806 if (h != NULL
1807 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1808 goto do_default;
1809 /* Fall through. */
1810 /* Relocation is the offset of the entry for this symbol in
1811 the global offset table. */
1814 bfd_vma off;
1816 if (sgot == NULL)
1818 sgot = bfd_get_section_by_name (dynobj, ".got");
1819 BFD_ASSERT (sgot != NULL);
1822 if (h != NULL)
1824 bfd_boolean dyn;
1826 off = h->got.offset;
1827 BFD_ASSERT (off != (bfd_vma) - 1);
1828 dyn = elf_hash_table (info)->dynamic_sections_created;
1830 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
1831 || (info->shared
1832 && (info->symbolic
1833 || h->dynindx == -1
1834 || h->forced_local)
1835 && h->def_regular))
1837 /* This is actually a static link, or it is a
1838 -Bsymbolic link and the symbol is defined
1839 locally, or the symbol was forced to be local
1840 because of a version file.. We must initialize
1841 this entry in the global offset table. Since
1842 the offset must always be a multiple of 4, we
1843 use the least significant bit to record whether
1844 we have initialized it already.
1846 When doing a dynamic link, we create a .rela.got
1847 relocation entry to initialize the value. This
1848 is done in the finish_dynamic_symbol routine. */
1849 if ((off & 1) != 0)
1850 off &= ~1;
1851 else
1853 bfd_put_32 (output_bfd, relocation,
1854 sgot->contents + off);
1855 h->got.offset |= 1;
1858 else
1859 unresolved_reloc = FALSE;
1861 else
1863 BFD_ASSERT (local_got_offsets != NULL);
1864 off = local_got_offsets[r_symndx];
1865 BFD_ASSERT (off != (bfd_vma) - 1);
1867 /* The offset must always be a multiple of 4. We use
1868 the least significant bit to record whether we have
1869 already generated the necessary reloc. */
1870 if ((off & 1) != 0)
1871 off &= ~1;
1872 else
1874 bfd_put_32 (output_bfd, relocation, sgot->contents + off);
1876 if (info->shared)
1878 asection *s;
1879 Elf_Internal_Rela outrel;
1880 bfd_byte *loc;
1882 s = bfd_get_section_by_name (dynobj, ".rela.got");
1883 BFD_ASSERT (s != NULL);
1885 outrel.r_offset = (sgot->output_section->vma
1886 + sgot->output_offset + off);
1887 outrel.r_info =
1888 ELF32_R_INFO (0, R_pcrel24);
1889 outrel.r_addend = relocation;
1890 loc = s->contents;
1891 loc +=
1892 s->reloc_count++ * sizeof (Elf32_External_Rela);
1893 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1896 local_got_offsets[r_symndx] |= 1;
1900 relocation = sgot->output_offset + off;
1901 rel->r_addend = 0;
1902 /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
1903 relocation /= 4;
1905 goto do_default;
1907 case R_pcrel24:
1908 case R_pcrel24_jump_l:
1910 bfd_vma x;
1912 relocation += rel->r_addend;
1914 /* Perform usual pc-relative correction. */
1915 relocation -= input_section->output_section->vma + input_section->output_offset;
1916 relocation -= address;
1918 /* We are getting reloc_entry->address 2 byte off from
1919 the start of instruction. Assuming absolute postion
1920 of the reloc data. But, following code had been written assuming
1921 reloc address is starting at begining of instruction.
1922 To compensate that I have increased the value of
1923 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
1925 relocation += 2;
1926 address -= 2;
1928 relocation >>= 1;
1930 x = bfd_get_16 (input_bfd, contents + address);
1931 x = (x & 0xff00) | ((relocation >> 16) & 0xff);
1932 bfd_put_16 (input_bfd, x, contents + address);
1934 x = bfd_get_16 (input_bfd, contents + address + 2);
1935 x = relocation & 0xFFFF;
1936 bfd_put_16 (input_bfd, x, contents + address + 2);
1937 r = bfd_reloc_ok;
1939 break;
1941 default:
1942 do_default:
1943 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1944 contents, address,
1945 relocation, rel->r_addend);
1947 break;
1950 done_reloc:
1951 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
1952 because such sections are not SEC_ALLOC and thus ld.so will
1953 not process them. */
1954 if (unresolved_reloc
1955 && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
1957 (*_bfd_error_handler)
1958 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
1959 input_bfd,
1960 input_section, (long) rel->r_offset, h->root.root.string);
1961 return FALSE;
1964 if (r != bfd_reloc_ok)
1966 const char *name;
1968 if (h != NULL)
1969 name = h->root.root.string;
1970 else
1972 name = bfd_elf_string_from_elf_section (input_bfd,
1973 symtab_hdr->sh_link,
1974 sym->st_name);
1975 if (name == NULL)
1976 return FALSE;
1977 if (*name == '\0')
1978 name = bfd_section_name (input_bfd, sec);
1981 if (r == bfd_reloc_overflow)
1983 if (!(info->callbacks->reloc_overflow
1984 (info, (h ? &h->root : NULL), name, howto->name,
1985 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
1986 return FALSE;
1988 else
1990 (*_bfd_error_handler)
1991 (_("%B(%A+0x%lx): reloc against `%s': error %d"),
1992 input_bfd, input_section,
1993 (long) rel->r_offset, name, (int) r);
1994 return FALSE;
1999 return TRUE;
2002 static asection *
2003 bfin_gc_mark_hook (asection * sec,
2004 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2005 Elf_Internal_Rela * rel,
2006 struct elf_link_hash_entry *h,
2007 Elf_Internal_Sym * sym)
2009 if (h != NULL)
2011 switch (ELF32_R_TYPE (rel->r_info))
2014 case R_BFIN_GNU_VTINHERIT:
2015 case R_BFIN_GNU_VTENTRY:
2016 break;
2018 default:
2019 switch (h->root.type)
2021 default:
2022 break;
2024 case bfd_link_hash_defined:
2025 case bfd_link_hash_defweak:
2026 return h->root.u.def.section;
2028 case bfd_link_hash_common:
2029 return h->root.u.c.p->section;
2033 else
2034 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
2036 return NULL;
2040 /* Update the got entry reference counts for the section being removed. */
2042 static bfd_boolean
2043 bfin_gc_sweep_hook (bfd * abfd,
2044 struct bfd_link_info *info,
2045 asection * sec,
2046 const Elf_Internal_Rela * relocs)
2048 Elf_Internal_Shdr *symtab_hdr;
2049 struct elf_link_hash_entry **sym_hashes;
2050 bfd_signed_vma *local_got_refcounts;
2051 const Elf_Internal_Rela *rel, *relend;
2052 bfd *dynobj;
2053 asection *sgot;
2054 asection *srelgot;
2056 dynobj = elf_hash_table (info)->dynobj;
2057 if (dynobj == NULL)
2058 return TRUE;
2060 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2061 sym_hashes = elf_sym_hashes (abfd);
2062 local_got_refcounts = elf_local_got_refcounts (abfd);
2064 sgot = bfd_get_section_by_name (dynobj, ".got");
2065 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
2067 relend = relocs + sec->reloc_count;
2068 for (rel = relocs; rel < relend; rel++)
2070 unsigned long r_symndx;
2071 struct elf_link_hash_entry *h;
2073 switch (ELF32_R_TYPE (rel->r_info))
2075 case R_got:
2076 r_symndx = ELF32_R_SYM (rel->r_info);
2077 if (r_symndx >= symtab_hdr->sh_info)
2079 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2080 if (h->got.refcount > 0)
2082 --h->got.refcount;
2083 if (h->got.refcount == 0)
2085 /* We don't need the .got entry any more. */
2086 sgot->size -= 4;
2087 srelgot->size -= sizeof (Elf32_External_Rela);
2091 else if (local_got_refcounts != NULL)
2093 if (local_got_refcounts[r_symndx] > 0)
2095 --local_got_refcounts[r_symndx];
2096 if (local_got_refcounts[r_symndx] == 0)
2098 /* We don't need the .got entry any more. */
2099 sgot->size -= 4;
2100 if (info->shared)
2101 srelgot->size -= sizeof (Elf32_External_Rela);
2105 break;
2106 default:
2107 break;
2111 return TRUE;
2115 /* Merge backend specific data from an object file to the output
2116 object file when linking. */
2117 static bfd_boolean
2118 elf32_bfin_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
2120 flagword out_flags;
2121 flagword in_flags;
2123 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2124 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
2125 return TRUE;
2127 in_flags = elf_elfheader (ibfd)->e_flags;
2128 out_flags = elf_elfheader (obfd)->e_flags;
2130 if (!elf_flags_init (obfd))
2132 elf_flags_init (obfd) = TRUE;
2133 elf_elfheader (obfd)->e_flags = in_flags;
2136 return TRUE;
2140 static bfd_boolean
2141 elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
2143 elf_elfheader (abfd)->e_flags = flags;
2144 elf_flags_init (abfd) = TRUE;
2145 return TRUE;
2149 /* Display the flags field. */
2150 static bfd_boolean
2151 elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
2153 FILE *file = (FILE *) ptr;
2155 BFD_ASSERT (abfd != NULL && ptr != NULL);
2157 /* Print normal ELF private data. */
2158 _bfd_elf_print_private_bfd_data (abfd, ptr);
2160 /* Ignore init flag - it may not be set, despite the flags field
2161 containing valid data. */
2163 /* xgettext:c-format */
2164 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
2166 fputc ('\n', file);
2168 return TRUE;
2171 /* bfin ELF linker hash entry. */
2173 struct bfin_link_hash_entry
2175 struct elf_link_hash_entry root;
2177 /* Number of PC relative relocs copied for this symbol. */
2178 struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
2181 /* bfin ELF linker hash table. */
2183 struct bfin_link_hash_table
2185 struct elf_link_hash_table root;
2187 /* Small local sym to section mapping cache. */
2188 struct sym_sec_cache sym_sec;
2191 #define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
2193 static struct bfd_hash_entry *
2194 bfin_link_hash_newfunc (struct bfd_hash_entry *entry,
2195 struct bfd_hash_table *table, const char *string)
2197 struct bfd_hash_entry *ret = entry;
2199 /* Allocate the structure if it has not already been allocated by a
2200 subclass. */
2201 if (ret == NULL)
2202 ret = bfd_hash_allocate (table, sizeof (struct bfin_link_hash_entry));
2203 if (ret == NULL)
2204 return ret;
2206 /* Call the allocation method of the superclass. */
2207 ret = _bfd_elf_link_hash_newfunc (ret, table, string);
2208 if (ret != NULL)
2209 bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;
2211 return ret;
2214 /* Create an bfin ELF linker hash table. */
2216 static struct bfd_link_hash_table *
2217 bfin_link_hash_table_create (bfd * abfd)
2219 struct bfin_link_hash_table *ret;
2220 bfd_size_type amt = sizeof (struct bfin_link_hash_table);
2222 ret = (struct bfin_link_hash_table *) bfd_malloc (amt);
2223 if (ret == (struct bfin_link_hash_table *) NULL)
2224 return NULL;
2226 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
2227 bfin_link_hash_newfunc))
2229 free (ret);
2230 return NULL;
2233 ret->sym_sec.abfd = NULL;
2235 return &ret->root.root;
2238 /* The size in bytes of an entry in the procedure linkage table. */
2240 /* Finish up the dynamic sections. */
2242 static bfd_boolean
2243 bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
2244 struct bfd_link_info *info)
2246 bfd *dynobj;
2247 asection *sdyn;
2249 dynobj = elf_hash_table (info)->dynobj;
2251 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
2253 if (elf_hash_table (info)->dynamic_sections_created)
2255 Elf32_External_Dyn *dyncon, *dynconend;
2257 BFD_ASSERT (sdyn != NULL);
2259 dyncon = (Elf32_External_Dyn *) sdyn->contents;
2260 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2261 for (; dyncon < dynconend; dyncon++)
2263 Elf_Internal_Dyn dyn;
2265 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2270 return TRUE;
2273 /* Finish up dynamic symbol handling. We set the contents of various
2274 dynamic sections here. */
2276 static bfd_boolean
2277 bfin_finish_dynamic_symbol (bfd * output_bfd,
2278 struct bfd_link_info *info,
2279 struct elf_link_hash_entry *h,
2280 Elf_Internal_Sym * sym)
2282 bfd *dynobj;
2284 dynobj = elf_hash_table (info)->dynobj;
2286 if (h->got.offset != (bfd_vma) - 1)
2288 asection *sgot;
2289 asection *srela;
2290 Elf_Internal_Rela rela;
2291 bfd_byte *loc;
2293 /* This symbol has an entry in the global offset table.
2294 Set it up. */
2296 sgot = bfd_get_section_by_name (dynobj, ".got");
2297 srela = bfd_get_section_by_name (dynobj, ".rela.got");
2298 BFD_ASSERT (sgot != NULL && srela != NULL);
2300 rela.r_offset = (sgot->output_section->vma
2301 + sgot->output_offset
2302 + (h->got.offset & ~(bfd_vma) 1));
2304 /* If this is a -Bsymbolic link, and the symbol is defined
2305 locally, we just want to emit a RELATIVE reloc. Likewise if
2306 the symbol was forced to be local because of a version file.
2307 The entry in the global offset table will already have been
2308 initialized in the relocate_section function. */
2309 if (info->shared
2310 && (info->symbolic
2311 || h->dynindx == -1 || h->forced_local) && h->def_regular)
2313 fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
2314 rela.r_info = ELF32_R_INFO (0, R_pcrel24);
2315 rela.r_addend = bfd_get_signed_32 (output_bfd,
2316 (sgot->contents
2318 (h->got.
2319 offset & ~(bfd_vma) 1)));
2321 else
2323 bfd_put_32 (output_bfd, (bfd_vma) 0,
2324 sgot->contents + (h->got.offset & ~(bfd_vma) 1));
2325 rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
2326 rela.r_addend = 0;
2329 loc = srela->contents;
2330 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
2331 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2334 if (h->needs_copy)
2336 BFD_ASSERT (0);
2338 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2339 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2340 || h == elf_hash_table (info)->hgot)
2341 sym->st_shndx = SHN_ABS;
2343 return TRUE;
2346 /* Adjust a symbol defined by a dynamic object and referenced by a
2347 regular object. The current definition is in some section of the
2348 dynamic object, but we're not including those sections. We have to
2349 change the definition to something the rest of the link can
2350 understand. */
2352 static bfd_boolean
2353 bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
2354 struct elf_link_hash_entry *h)
2356 bfd *dynobj;
2357 asection *s;
2358 unsigned int power_of_two;
2360 dynobj = elf_hash_table (info)->dynobj;
2362 /* Make sure we know what is going on here. */
2363 BFD_ASSERT (dynobj != NULL
2364 && (h->needs_plt
2365 || h->u.weakdef != NULL
2366 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2368 /* If this is a function, put it in the procedure linkage table. We
2369 will fill in the contents of the procedure linkage table later,
2370 when we know the address of the .got section. */
2371 if (h->type == STT_FUNC || h->needs_plt)
2373 BFD_ASSERT(0);
2376 /* If this is a weak symbol, and there is a real definition, the
2377 processor independent code will have arranged for us to see the
2378 real definition first, and we can just use the same value. */
2379 if (h->u.weakdef != NULL)
2381 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2382 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2383 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2384 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2385 return TRUE;
2388 /* This is a reference to a symbol defined by a dynamic object which
2389 is not a function. */
2391 /* If we are creating a shared library, we must presume that the
2392 only references to the symbol are via the global offset table.
2393 For such cases we need not do anything here; the relocations will
2394 be handled correctly by relocate_section. */
2395 if (info->shared)
2396 return TRUE;
2398 /* We must allocate the symbol in our .dynbss section, which will
2399 become part of the .bss section of the executable. There will be
2400 an entry for this symbol in the .dynsym section. The dynamic
2401 object will contain position independent code, so all references
2402 from the dynamic object to this symbol will go through the global
2403 offset table. The dynamic linker will use the .dynsym entry to
2404 determine the address it must put in the global offset table, so
2405 both the dynamic object and the regular object will refer to the
2406 same memory location for the variable. */
2408 s = bfd_get_section_by_name (dynobj, ".dynbss");
2409 BFD_ASSERT (s != NULL);
2411 /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
2412 copy the initial value out of the dynamic object and into the
2413 runtime process image. We need to remember the offset into the
2414 .rela.bss section we are going to use. */
2415 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2417 asection *srel;
2419 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2420 BFD_ASSERT (srel != NULL);
2421 srel->size += sizeof (Elf32_External_Rela);
2422 h->needs_copy = 1;
2425 /* We need to figure out the alignment required for this symbol. I
2426 have no idea how ELF linkers handle this. */
2427 power_of_two = bfd_log2 (h->size);
2428 if (power_of_two > 3)
2429 power_of_two = 3;
2431 /* Apply the required alignment. */
2432 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2433 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2435 if (!bfd_set_section_alignment (dynobj, s, power_of_two))
2436 return FALSE;
2439 /* Define the symbol as being at this point in the section. */
2440 h->root.u.def.section = s;
2441 h->root.u.def.value = s->size;
2443 /* Increment the section size to make room for the symbol. */
2444 s->size += h->size;
2446 return TRUE;
2449 /* The bfin linker needs to keep track of the number of relocs that it
2450 decides to copy in check_relocs for each symbol. This is so that it
2451 can discard PC relative relocs if it doesn't need them when linking
2452 with -Bsymbolic. We store the information in a field extending the
2453 regular ELF linker hash table. */
2455 /* This structure keeps track of the number of PC relative relocs we have
2456 copied for a given symbol. */
2458 struct bfin_pcrel_relocs_copied
2460 /* Next section. */
2461 struct bfin_pcrel_relocs_copied *next;
2462 /* A section in dynobj. */
2463 asection *section;
2464 /* Number of relocs copied in this section. */
2465 bfd_size_type count;
2468 /* This function is called via elf_link_hash_traverse if we are
2469 creating a shared object. In the -Bsymbolic case it discards the
2470 space allocated to copy PC relative relocs against symbols which
2471 are defined in regular objects. For the normal shared case, it
2472 discards space for pc-relative relocs that have become local due to
2473 symbol visibility changes. We allocated space for them in the
2474 check_relocs routine, but we won't fill them in in the
2475 relocate_section routine.
2477 We also check whether any of the remaining relocations apply
2478 against a readonly section, and set the DF_TEXTREL flag in this
2479 case. */
2481 static bfd_boolean
2482 bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
2484 struct bfd_link_info *info = (struct bfd_link_info *) inf;
2485 struct bfin_pcrel_relocs_copied *s;
2487 if (h->root.type == bfd_link_hash_warning)
2488 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2490 if (!h->def_regular || (!info->symbolic && !h->forced_local))
2492 if ((info->flags & DF_TEXTREL) == 0)
2494 /* Look for relocations against read-only sections. */
2495 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
2496 s != NULL; s = s->next)
2497 if ((s->section->flags & SEC_READONLY) != 0)
2499 info->flags |= DF_TEXTREL;
2500 break;
2504 return TRUE;
2507 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
2508 s != NULL; s = s->next)
2509 s->section->size -= s->count * sizeof (Elf32_External_Rela);
2511 return TRUE;
2514 /* Set the sizes of the dynamic sections. */
2515 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
2517 static bfd_boolean
2518 bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
2519 struct bfd_link_info *info)
2521 bfd *dynobj;
2522 asection *s;
2523 bfd_boolean relocs;
2525 dynobj = elf_hash_table (info)->dynobj;
2526 BFD_ASSERT (dynobj != NULL);
2528 if (elf_hash_table (info)->dynamic_sections_created)
2530 /* Set the contents of the .interp section to the interpreter. */
2531 if (info->executable)
2533 s = bfd_get_section_by_name (dynobj, ".interp");
2534 BFD_ASSERT (s != NULL);
2535 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2536 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2539 else
2541 /* We may have created entries in the .rela.got section.
2542 However, if we are not creating the dynamic sections, we will
2543 not actually use these entries. Reset the size of .rela.got,
2544 which will cause it to get stripped from the output file
2545 below. */
2546 s = bfd_get_section_by_name (dynobj, ".rela.got");
2547 if (s != NULL)
2548 s->size = 0;
2551 /* If this is a -Bsymbolic shared link, then we need to discard all
2552 PC relative relocs against symbols defined in a regular object.
2553 For the normal shared case we discard the PC relative relocs
2554 against symbols that have become local due to visibility changes.
2555 We allocated space for them in the check_relocs routine, but we
2556 will not fill them in in the relocate_section routine. */
2557 if (info->shared)
2558 elf_link_hash_traverse (elf_hash_table (info),
2559 bfin_discard_copies, (PTR) info);
2561 /* The check_relocs and adjust_dynamic_symbol entry points have
2562 determined the sizes of the various dynamic sections. Allocate
2563 memory for them. */
2564 relocs = FALSE;
2565 for (s = dynobj->sections; s != NULL; s = s->next)
2567 const char *name;
2568 bfd_boolean strip;
2570 if ((s->flags & SEC_LINKER_CREATED) == 0)
2571 continue;
2573 /* It's OK to base decisions on the section name, because none
2574 of the dynobj section names depend upon the input files. */
2575 name = bfd_get_section_name (dynobj, s);
2577 strip = FALSE;
2579 if (strncmp (name, ".rela", 5) == 0)
2581 if (s->size == 0)
2583 /* If we don't need this section, strip it from the
2584 output file. This is mostly to handle .rela.bss and
2585 .rela.plt. We must create both sections in
2586 create_dynamic_sections, because they must be created
2587 before the linker maps input sections to output
2588 sections. The linker does that before
2589 adjust_dynamic_symbol is called, and it is that
2590 function which decides whether anything needs to go
2591 into these sections. */
2592 strip = TRUE;
2594 else
2596 relocs = TRUE;
2598 /* We use the reloc_count field as a counter if we need
2599 to copy relocs into the output file. */
2600 s->reloc_count = 0;
2603 else if (strncmp (name, ".got", 4) != 0)
2605 /* It's not one of our sections, so don't allocate space. */
2606 continue;
2609 if (strip)
2611 s->flags |= SEC_EXCLUDE;
2612 continue;
2615 /* Allocate memory for the section contents. */
2616 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
2617 Unused entries should be reclaimed before the section's contents
2618 are written out, but at the moment this does not happen. Thus in
2619 order to prevent writing out garbage, we initialise the section's
2620 contents to zero. */
2621 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2622 if (s->contents == NULL && s->size != 0)
2623 return FALSE;
2626 if (elf_hash_table (info)->dynamic_sections_created)
2628 /* Add some entries to the .dynamic section. We fill in the
2629 values later, in bfin_finish_dynamic_sections, but we
2630 must add the entries now so that we get the correct size for
2631 the .dynamic section. The DT_DEBUG entry is filled in by the
2632 dynamic linker and used by the debugger. */
2633 #define add_dynamic_entry(TAG, VAL) \
2634 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2636 if (!info->shared)
2638 if (!add_dynamic_entry (DT_DEBUG, 0))
2639 return FALSE;
2643 if (relocs)
2645 if (!add_dynamic_entry (DT_RELA, 0)
2646 || !add_dynamic_entry (DT_RELASZ, 0)
2647 || !add_dynamic_entry (DT_RELAENT,
2648 sizeof (Elf32_External_Rela)))
2649 return FALSE;
2652 if ((info->flags & DF_TEXTREL) != 0)
2654 if (!add_dynamic_entry (DT_TEXTREL, 0))
2655 return FALSE;
2658 #undef add_dynamic_entry
2660 return TRUE;
2663 /* Given a .data section and a .emreloc in-memory section, store
2664 relocation information into the .emreloc section which can be
2665 used at runtime to relocate the section. This is called by the
2666 linker when the --embedded-relocs switch is used. This is called
2667 after the add_symbols entry point has been called for all the
2668 objects, and before the final_link entry point is called. */
2670 bfd_boolean
2671 bfd_bfin_elf32_create_embedded_relocs (
2672 bfd *abfd,
2673 struct bfd_link_info *info,
2674 asection *datasec,
2675 asection *relsec,
2676 char **errmsg)
2678 Elf_Internal_Shdr *symtab_hdr;
2679 Elf_Internal_Sym *isymbuf = NULL;
2680 Elf_Internal_Rela *internal_relocs = NULL;
2681 Elf_Internal_Rela *irel, *irelend;
2682 bfd_byte *p;
2683 bfd_size_type amt;
2685 BFD_ASSERT (! info->relocatable);
2687 *errmsg = NULL;
2689 if (datasec->reloc_count == 0)
2690 return TRUE;
2692 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2694 /* Get a copy of the native relocations. */
2695 internal_relocs = (_bfd_elf_link_read_relocs
2696 (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
2697 info->keep_memory));
2698 if (internal_relocs == NULL)
2699 goto error_return;
2701 amt = (bfd_size_type) datasec->reloc_count * 12;
2702 relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2703 if (relsec->contents == NULL)
2704 goto error_return;
2706 p = relsec->contents;
2708 irelend = internal_relocs + datasec->reloc_count;
2709 for (irel = internal_relocs; irel < irelend; irel++, p += 12)
2711 asection *targetsec;
2713 /* We are going to write a four byte longword into the runtime
2714 reloc section. The longword will be the address in the data
2715 section which must be relocated. It is followed by the name
2716 of the target section NUL-padded or truncated to 8
2717 characters. */
2719 /* We can only relocate absolute longword relocs at run time. */
2720 if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
2722 *errmsg = _("unsupported reloc type");
2723 bfd_set_error (bfd_error_bad_value);
2724 goto error_return;
2727 /* Get the target section referred to by the reloc. */
2728 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2730 /* A local symbol. */
2731 Elf_Internal_Sym *isym;
2733 /* Read this BFD's local symbols if we haven't done so already. */
2734 if (isymbuf == NULL)
2736 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2737 if (isymbuf == NULL)
2738 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2739 symtab_hdr->sh_info, 0,
2740 NULL, NULL, NULL);
2741 if (isymbuf == NULL)
2742 goto error_return;
2745 isym = isymbuf + ELF32_R_SYM (irel->r_info);
2746 targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2748 else
2750 unsigned long indx;
2751 struct elf_link_hash_entry *h;
2753 /* An external symbol. */
2754 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2755 h = elf_sym_hashes (abfd)[indx];
2756 BFD_ASSERT (h != NULL);
2757 if (h->root.type == bfd_link_hash_defined
2758 || h->root.type == bfd_link_hash_defweak)
2759 targetsec = h->root.u.def.section;
2760 else
2761 targetsec = NULL;
2764 bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2765 memset (p + 4, 0, 8);
2766 if (targetsec != NULL)
2767 strncpy ((char *) p + 4, targetsec->output_section->name, 8);
2770 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2771 free (isymbuf);
2772 if (internal_relocs != NULL
2773 && elf_section_data (datasec)->relocs != internal_relocs)
2774 free (internal_relocs);
2775 return TRUE;
2777 error_return:
2778 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2779 free (isymbuf);
2780 if (internal_relocs != NULL
2781 && elf_section_data (datasec)->relocs != internal_relocs)
2782 free (internal_relocs);
2783 return FALSE;
2786 #define TARGET_LITTLE_SYM bfd_elf32_bfin_vec
2787 #define TARGET_LITTLE_NAME "elf32-bfin"
2788 #define ELF_ARCH bfd_arch_bfin
2789 #define ELF_MACHINE_CODE EM_BLACKFIN
2790 #define ELF_MAXPAGESIZE 0x1000
2791 #define elf_symbol_leading_char '_'
2793 #define bfd_elf32_bfd_reloc_type_lookup bfin_bfd_reloc_type_lookup
2794 #define elf_info_to_howto bfin_info_to_howto
2795 #define elf_info_to_howto_rel 0
2797 #define bfd_elf32_bfd_is_local_label_name \
2798 bfin_is_local_label_name
2799 #define bfin_hash_table(p) \
2800 ((struct bfin_link_hash_table *) (p)->hash)
2804 #define elf_backend_create_dynamic_sections \
2805 _bfd_elf_create_dynamic_sections
2806 #define bfd_elf32_bfd_link_hash_table_create \
2807 bfin_link_hash_table_create
2808 #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
2810 #define elf_backend_check_relocs bfin_check_relocs
2811 #define elf_backend_adjust_dynamic_symbol \
2812 bfin_adjust_dynamic_symbol
2813 #define elf_backend_size_dynamic_sections \
2814 bfin_size_dynamic_sections
2815 #define elf_backend_relocate_section bfin_relocate_section
2816 #define elf_backend_finish_dynamic_symbol \
2817 bfin_finish_dynamic_symbol
2818 #define elf_backend_finish_dynamic_sections \
2819 bfin_finish_dynamic_sections
2820 #define elf_backend_gc_mark_hook bfin_gc_mark_hook
2821 #define elf_backend_gc_sweep_hook bfin_gc_sweep_hook
2822 #define bfd_elf32_bfd_merge_private_bfd_data \
2823 elf32_bfin_merge_private_bfd_data
2824 #define bfd_elf32_bfd_set_private_flags \
2825 elf32_bfin_set_private_flags
2826 #define bfd_elf32_bfd_print_private_bfd_data \
2827 elf32_bfin_print_private_bfd_data
2828 #define elf_backend_reloc_type_class elf32_bfin_reloc_type_class
2829 #define elf_backend_can_gc_sections 1
2830 #define elf_backend_can_refcount 1
2831 #define elf_backend_want_got_plt 0
2832 #define elf_backend_plt_readonly 1
2833 #define elf_backend_want_plt_sym 0
2834 #define elf_backend_got_header_size 12
2835 #define elf_backend_rela_normal 1
2838 #include "elf32-target.h"