bfd/
[binutils.git] / bfd / elf32-bfin.c
blob72f8aee5c96e6aed928ce65c775688e52a2028e8
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 if (symbol->flags & BSF_SECTION_SYM)
438 /* Add in supplied addend. */
439 relocation += reloc_entry->addend;
442 else
444 relocation = reloc_stack_pop ();
447 if (relocatable)
449 reloc_entry->address += input_section->output_offset;
450 reloc_entry->addend += symbol->section->output_offset;
452 else
454 reloc_entry->addend = 0;
457 if (howto->complain_on_overflow != complain_overflow_dont)
459 bfd_reloc_status_type flag;
460 flag = bfd_check_overflow (howto->complain_on_overflow,
461 howto->bitsize,
462 howto->rightshift,
463 bfd_arch_bits_per_address(abfd),
464 relocation);
465 if (flag != bfd_reloc_ok)
466 return flag;
470 /* Here the variable relocation holds the final address of the
471 symbol we are relocating against, plus any addend. */
473 x = bfd_get_16 (abfd, (bfd_byte *) data + reloc_addr);
474 relocation >>= (bfd_vma) howto->rightshift;
475 x = relocation;
476 bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
477 return bfd_reloc_ok;
481 static bfd_reloc_status_type
482 bfin_byte4_reloc (bfd *abfd,
483 arelent *reloc_entry,
484 asymbol *symbol,
485 PTR data,
486 asection *input_section,
487 bfd *output_bfd,
488 char **error_message ATTRIBUTE_UNUSED)
490 bfd_vma relocation, x;
491 bfd_size_type addr = reloc_entry->address;
492 bfd_vma output_base = 0;
493 asection *output_section;
494 bfd_boolean relocatable = (output_bfd != NULL);
496 /* Is the address of the relocation really within the section? */
497 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
498 return bfd_reloc_outofrange;
500 if (is_reloc_stack_empty ())
502 if (bfd_is_und_section (symbol->section)
503 && (symbol->flags & BSF_WEAK) == 0
504 && !relocatable)
505 return bfd_reloc_undefined;
507 output_section = symbol->section->output_section;
508 relocation = symbol->value;
509 /* Convert input-section-relative symbol value to absolute. */
510 if (relocatable)
511 output_base = 0;
512 else
513 output_base = output_section->vma;
515 if ((symbol->name
516 && symbol->section->name
517 && !strcmp (symbol->name, symbol->section->name))
518 || !relocatable)
520 relocation += output_base + symbol->section->output_offset;
523 relocation += reloc_entry->addend;
525 else
527 relocation = reloc_stack_pop();
528 relocation += reloc_entry->addend;
531 if (relocatable)
533 /* This output will be relocatable ... like ld -r. */
534 reloc_entry->address += input_section->output_offset;
535 reloc_entry->addend += symbol->section->output_offset;
537 else
539 reloc_entry->addend = 0;
542 /* Here the variable relocation holds the final address of the
543 symbol we are relocating against, plus any addend. */
544 x = relocation & 0xFFFF0000;
545 x >>=16;
546 bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
548 x = relocation & 0x0000FFFF;
549 bfd_put_16 (abfd, x, (unsigned char *) data + addr);
550 return bfd_reloc_ok;
553 /* bfin_bfd_reloc handles the blackfin arithmetic relocations.
554 Use this instead of bfd_perform_relocation. */
555 static bfd_reloc_status_type
556 bfin_bfd_reloc (bfd *abfd,
557 arelent *reloc_entry,
558 asymbol *symbol,
559 PTR data,
560 asection *input_section,
561 bfd *output_bfd,
562 char **error_message ATTRIBUTE_UNUSED)
564 bfd_vma relocation;
565 bfd_size_type addr = reloc_entry->address;
566 bfd_vma output_base = 0;
567 reloc_howto_type *howto = reloc_entry->howto;
568 asection *output_section;
569 bfd_boolean relocatable = (output_bfd != NULL);
571 /* Is the address of the relocation really within the section? */
572 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
573 return bfd_reloc_outofrange;
575 if (is_reloc_stack_empty())
577 if (bfd_is_und_section (symbol->section)
578 && (symbol->flags & BSF_WEAK) == 0
579 && !relocatable)
580 return bfd_reloc_undefined;
582 /* Get symbol value. (Common symbols are special.) */
583 if (bfd_is_com_section (symbol->section))
584 relocation = 0;
585 else
586 relocation = symbol->value;
588 output_section = symbol->section->output_section;
590 /* Convert input-section-relative symbol value to absolute. */
591 if (relocatable)
592 output_base = 0;
593 else
594 output_base = output_section->vma;
596 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
597 relocation += output_base + symbol->section->output_offset;
599 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
601 /* Add in supplied addend. */
602 relocation += reloc_entry->addend;
606 else
608 relocation = reloc_stack_pop();
611 /* Here the variable relocation holds the final address of the
612 symbol we are relocating against, plus any addend. */
614 if (howto->pc_relative == TRUE)
616 relocation -= input_section->output_section->vma + input_section->output_offset;
618 if (howto->pcrel_offset == TRUE)
619 relocation -= reloc_entry->address;
622 if (relocatable)
624 reloc_entry->address += input_section->output_offset;
625 reloc_entry->addend += symbol->section->output_offset;
628 if (howto->complain_on_overflow != complain_overflow_dont)
630 bfd_reloc_status_type status;
632 status = bfd_check_overflow (howto->complain_on_overflow,
633 howto->bitsize,
634 howto->rightshift,
635 bfd_arch_bits_per_address(abfd),
636 relocation);
637 if (status != bfd_reloc_ok)
638 return status;
641 /* If rightshift is 1 and the number odd, return error. */
642 if (howto->rightshift && (relocation & 0x01))
644 fprintf(stderr, "relocation should be even number\n");
645 return bfd_reloc_overflow;
648 relocation >>= (bfd_vma) howto->rightshift;
650 /* Shift everything up to where it's going to be used. */
652 relocation <<= (bfd_vma) howto->bitpos;
654 #define DOIT(x) \
655 x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
657 /* handle 8 and 16 bit relocations here. */
658 switch (howto->size)
660 case 0:
662 char x = bfd_get_8 (abfd, (char *) data + addr);
663 DOIT (x);
664 bfd_put_8 (abfd, x, (unsigned char *) data + addr);
666 break;
668 case 1:
670 unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
671 DOIT (x);
672 bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
674 break;
676 default:
677 return bfd_reloc_other;
680 return bfd_reloc_ok;
683 #if 0
684 static bfd_reloc_status_type bfin_bfd_reloc
685 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
687 static bfd_reloc_status_type bfin_imm16_reloc
688 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
690 static bfd_reloc_status_type bfin_pcrel24_reloc
691 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
693 static bfd_reloc_status_type bfin_pltpc_reloc
694 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
696 static bfd_reloc_status_type bfin_const_reloc
697 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
699 static bfd_reloc_status_type bfin_oper_reloc
700 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
702 static bfd_reloc_status_type bfin_byte4_reloc
703 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
705 static bfd_reloc_status_type bfin_push_reloc
706 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
708 static bfd_boolean bfin_is_local_label_name
709 PARAMS ((bfd *, const char *));
710 #endif
711 bfd_boolean bfd_bfin_elf32_create_embedded_relocs
712 PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
715 /* HOWTO Table for blackfin.
716 Blackfin relocations are fairly complicated.
717 Some of the salient features are
718 a. Even numbered offsets. A number of (not all) relocations are
719 even numbered. This means that the rightmost bit is not stored.
720 Needs to right shift by 1 and check to see if value is not odd
721 b. A relocation can be an expression. An expression takes on
722 a variety of relocations arranged in a stack.
723 As a result, we cannot use the standard generic function as special
724 function. We will have our own, which is very similar to the standard
725 generic function except that it understands how to get the value from
726 the relocation stack. . */
728 #define BFIN_RELOC_MIN 0
729 #define BFIN_RELOC_MAX 0x13
730 #define BFIN_GNUEXT_RELOC_MIN 0x40
731 #define BFIN_GNUEXT_RELOC_MAX 0x43
732 #define BFIN_ARELOC_MIN 0xE0
733 #define BFIN_ARELOC_MAX 0xF3
735 static reloc_howto_type bfin_howto_table [] =
737 /* This reloc does nothing. . */
738 HOWTO (R_unused0, /* type. */
739 0, /* rightshift. */
740 2, /* size (0 = byte, 1 = short, 2 = long). */
741 32, /* bitsize. */
742 FALSE, /* pc_relative. */
743 0, /* bitpos. */
744 complain_overflow_bitfield, /* complain_on_overflow. */
745 bfd_elf_generic_reloc, /* special_function. */
746 "R_unused0", /* name. */
747 FALSE, /* partial_inplace. */
748 0, /* src_mask. */
749 0, /* dst_mask. */
750 FALSE), /* pcrel_offset. */
752 HOWTO (R_pcrel5m2, /* type. */
753 1, /* rightshift. */
754 1, /* size (0 = byte, 1 = short, 2 = long).. */
755 4, /* bitsize. */
756 TRUE, /* pc_relative. */
757 0, /* bitpos. */
758 complain_overflow_unsigned, /* complain_on_overflow. */
759 bfin_bfd_reloc, /* special_function. */
760 "R_pcrel5m2", /* name. */
761 FALSE, /* partial_inplace. */
762 0x0000000F, /* src_mask. */
763 0x0000000F, /* dst_mask. */
764 FALSE), /* pcrel_offset. */
766 HOWTO (R_unused1, /* type. */
767 0, /* rightshift. */
768 2, /* size (0 = byte, 1 = short, 2 = long). */
769 32, /* bitsize. */
770 FALSE, /* pc_relative. */
771 0, /* bitpos. */
772 complain_overflow_bitfield, /* complain_on_overflow. */
773 bfd_elf_generic_reloc, /* special_function. */
774 "R_unused1", /* name. */
775 FALSE, /* partial_inplace. */
776 0, /* src_mask. */
777 0, /* dst_mask. */
778 FALSE), /* pcrel_offset. */
780 HOWTO (R_pcrel10, /* type. */
781 1, /* rightshift. */
782 1, /* size (0 = byte, 1 = short, 2 = long). */
783 10, /* bitsize. */
784 TRUE, /* pc_relative. */
785 0, /* bitpos. */
786 complain_overflow_signed, /* complain_on_overflow. */
787 bfin_bfd_reloc, /* special_function. */
788 "R_pcrel10", /* name. */
789 FALSE, /* partial_inplace. */
790 0x000003FF, /* src_mask. */
791 0x000003FF, /* dst_mask. */
792 TRUE), /* pcrel_offset. */
794 HOWTO (R_pcrel12_jump, /* type. */
795 1, /* rightshift. */
796 /* the offset is actually 13 bit
797 aligned on a word boundary so
798 only 12 bits have to be used.
799 Right shift the rightmost bit.. */
800 1, /* size (0 = byte, 1 = short, 2 = long). */
801 12, /* bitsize. */
802 TRUE, /* pc_relative. */
803 0, /* bitpos. */
804 complain_overflow_signed, /* complain_on_overflow. */
805 bfin_bfd_reloc, /* special_function. */
806 "R_pcrel12_jump", /* name. */
807 FALSE, /* partial_inplace. */
808 0x0FFF, /* src_mask. */
809 0x0FFF, /* dst_mask. */
810 TRUE), /* pcrel_offset. */
812 HOWTO (R_rimm16, /* type. */
813 0, /* rightshift. */
814 1, /* size (0 = byte, 1 = short, 2 = long). */
815 16, /* bitsize. */
816 FALSE, /* pc_relative. */
817 0, /* bitpos. */
818 complain_overflow_signed, /* complain_on_overflow. */
819 bfin_imm16_reloc, /* special_function. */
820 "R_rimm16", /* name. */
821 FALSE, /* partial_inplace. */
822 0x0000FFFF, /* src_mask. */
823 0x0000FFFF, /* dst_mask. */
824 TRUE), /* pcrel_offset. */
826 HOWTO (R_luimm16, /* type. */
827 0, /* rightshift. */
828 1, /* size (0 = byte, 1 = short, 2 = long). */
829 16, /* bitsize. */
830 FALSE, /* pc_relative. */
831 0, /* bitpos. */
832 complain_overflow_dont, /* complain_on_overflow. */
833 bfin_imm16_reloc, /* special_function. */
834 "R_luimm16", /* name. */
835 FALSE, /* partial_inplace. */
836 0x0000FFFF, /* src_mask. */
837 0x0000FFFF, /* dst_mask. */
838 TRUE), /* pcrel_offset. */
840 HOWTO (R_huimm16, /* type. */
841 16, /* rightshift. */
842 1, /* size (0 = byte, 1 = short, 2 = long). */
843 16, /* bitsize. */
844 FALSE, /* pc_relative. */
845 0, /* bitpos. */
846 complain_overflow_unsigned, /* complain_on_overflow. */
847 bfin_imm16_reloc, /* special_function. */
848 "R_huimm16", /* name. */
849 FALSE, /* partial_inplace. */
850 0x0000FFFF, /* src_mask. */
851 0x0000FFFF, /* dst_mask. */
852 TRUE), /* pcrel_offset. */
854 HOWTO (R_pcrel12_jump_s, /* type. */
855 1, /* rightshift. */
856 1, /* size (0 = byte, 1 = short, 2 = long). */
857 12, /* bitsize. */
858 TRUE, /* pc_relative. */
859 0, /* bitpos. */
860 complain_overflow_signed, /* complain_on_overflow. */
861 bfin_bfd_reloc, /* special_function. */
862 "R_pcrel12_jump_s", /* name. */
863 FALSE, /* partial_inplace. */
864 0x00000FFF, /* src_mask. */
865 0x00000FFF, /* dst_mask. */
866 TRUE), /* pcrel_offset. */
868 HOWTO (R_pcrel24_jump_x, /* type. */
869 1, /* rightshift. */
870 2, /* size (0 = byte, 1 = short, 2 = long). */
871 24, /* bitsize. */
872 TRUE, /* pc_relative. */
873 0, /* bitpos. */
874 complain_overflow_signed, /* complain_on_overflow. */
875 bfin_pcrel24_reloc, /* special_function. */
876 "R_pcrel24_jump_x", /* name. */
877 FALSE, /* partial_inplace. */
878 0x00FFFFFF, /* src_mask. */
879 0x00FFFFFF, /* dst_mask. */
880 TRUE), /* pcrel_offset. */
882 HOWTO (R_pcrel24, /* type. */
883 1, /* rightshift. */
884 2, /* size (0 = byte, 1 = short, 2 = long). */
885 24, /* bitsize. */
886 TRUE, /* pc_relative. */
887 0, /* bitpos. */
888 complain_overflow_signed, /* complain_on_overflow. */
889 bfin_pcrel24_reloc, /* special_function. */
890 "R_pcrel24", /* name. */
891 FALSE, /* partial_inplace. */
892 0x00FFFFFF, /* src_mask. */
893 0x00FFFFFF, /* dst_mask. */
894 TRUE), /* pcrel_offset. */
896 HOWTO (R_unusedb, /* type. */
897 0, /* rightshift. */
898 2, /* size (0 = byte, 1 = short, 2 = long). */
899 32, /* bitsize. */
900 FALSE, /* pc_relative. */
901 0, /* bitpos. */
902 complain_overflow_dont, /* complain_on_overflow. */
903 bfd_elf_generic_reloc, /* special_function. */
904 "R_unusedb", /* name. */
905 FALSE, /* partial_inplace. */
906 0, /* src_mask. */
907 0, /* dst_mask. */
908 FALSE), /* pcrel_offset. */
910 HOWTO (R_unusedc, /* type. */
911 0, /* rightshift. */
912 2, /* size (0 = byte, 1 = short, 2 = long). */
913 32, /* bitsize. */
914 FALSE, /* pc_relative. */
915 0, /* bitpos. */
916 complain_overflow_dont, /* complain_on_overflow. */
917 bfd_elf_generic_reloc, /* special_function. */
918 "R_unusedc", /* name. */
919 FALSE, /* partial_inplace. */
920 0, /* src_mask. */
921 0, /* dst_mask. */
922 FALSE), /* pcrel_offset. */
924 HOWTO (R_pcrel24_jump_l, /* type. */
925 1, /* rightshift. */
926 2, /* size (0 = byte, 1 = short, 2 = long). */
927 24, /* bitsize. */
928 TRUE, /* pc_relative. */
929 0, /* bitpos. */
930 complain_overflow_signed, /* complain_on_overflow. */
931 bfin_pcrel24_reloc, /* special_function. */
932 "R_pcrel24_jump_l", /* name. */
933 FALSE, /* partial_inplace. */
934 0x00FFFFFF, /* src_mask. */
935 0x00FFFFFF, /* dst_mask. */
936 TRUE), /* pcrel_offset. */
938 HOWTO (R_pcrel24_call_x, /* type. */
939 1, /* rightshift. */
940 2, /* size (0 = byte, 1 = short, 2 = long). */
941 24, /* bitsize. */
942 TRUE, /* pc_relative. */
943 0, /* bitpos. */
944 complain_overflow_signed, /* complain_on_overflow. */
945 bfin_pcrel24_reloc, /* special_function. */
946 "R_pcrel24_call_x", /* name. */
947 FALSE, /* partial_inplace. */
948 0x00FFFFFF, /* src_mask. */
949 0x00FFFFFF, /* dst_mask. */
950 TRUE), /* pcrel_offset. */
952 HOWTO (R_var_eq_symb, /* type. */
953 0, /* rightshift. */
954 2, /* size (0 = byte, 1 = short, 2 = long). */
955 32, /* bitsize. */
956 FALSE, /* pc_relative. */
957 0, /* bitpos. */
958 complain_overflow_bitfield, /* complain_on_overflow. */
959 bfin_bfd_reloc, /* special_function. */
960 "R_var_eq_symb", /* name. */
961 FALSE, /* partial_inplace. */
962 0, /* src_mask. */
963 0, /* dst_mask. */
964 FALSE), /* pcrel_offset. */
966 HOWTO (R_byte_data, /* type. */
967 0, /* rightshift. */
968 0, /* size (0 = byte, 1 = short, 2 = long). */
969 8, /* bitsize. */
970 FALSE, /* pc_relative. */
971 0, /* bitpos. */
972 complain_overflow_unsigned, /* complain_on_overflow. */
973 bfin_bfd_reloc, /* special_function. */
974 "R_byte_data", /* name. */
975 FALSE, /* partial_inplace. */
976 0xFF, /* src_mask. */
977 0xFF, /* dst_mask. */
978 TRUE), /* pcrel_offset. */
980 HOWTO (R_byte2_data, /* type. */
981 0, /* rightshift. */
982 1, /* size (0 = byte, 1 = short, 2 = long). */
983 16, /* bitsize. */
984 FALSE, /* pc_relative. */
985 0, /* bitpos. */
986 complain_overflow_signed, /* complain_on_overflow. */
987 bfin_bfd_reloc, /* special_function. */
988 "R_byte2_data", /* name. */
989 FALSE, /* partial_inplace. */
990 0xFFFF, /* src_mask. */
991 0xFFFF, /* dst_mask. */
992 TRUE), /* pcrel_offset. */
994 HOWTO (R_byte4_data, /* type. */
995 0, /* rightshift. */
996 2, /* size (0 = byte, 1 = short, 2 = long). */
997 32, /* bitsize. */
998 FALSE, /* pc_relative. */
999 0, /* bitpos. */
1000 complain_overflow_unsigned, /* complain_on_overflow. */
1001 bfin_byte4_reloc, /* special_function. */
1002 "R_byte4_data", /* name. */
1003 FALSE, /* partial_inplace. */
1004 0xFFFFFFFF, /* src_mask. */
1005 0xFFFFFFFF, /* dst_mask. */
1006 TRUE), /* pcrel_offset. */
1008 HOWTO (R_pcrel11, /* type. */
1009 1, /* rightshift. */
1010 1, /* size (0 = byte, 1 = short, 2 = long). */
1011 10, /* bitsize. */
1012 TRUE, /* pc_relative. */
1013 0, /* bitpos. */
1014 complain_overflow_unsigned, /* complain_on_overflow. */
1015 bfin_bfd_reloc, /* special_function. */
1016 "R_pcrel11", /* name. */
1017 FALSE, /* partial_inplace. */
1018 0x000003FF, /* src_mask. */
1019 0x000003FF, /* dst_mask. */
1020 FALSE), /* pcrel_offset. */
1023 static reloc_howto_type bfin_areloc_howto_table [] =
1025 HOWTO (R_push,
1029 FALSE,
1031 complain_overflow_dont,
1032 bfin_push_reloc,
1033 "R_expst_push",
1034 FALSE,
1037 FALSE),
1039 HOWTO (R_const,
1043 FALSE,
1045 complain_overflow_dont,
1046 bfin_const_reloc,
1047 "R_expst_const",
1048 FALSE,
1051 FALSE),
1053 HOWTO (R_add,
1057 FALSE,
1059 complain_overflow_dont,
1060 bfin_oper_reloc,
1061 "R_expst_add",
1062 FALSE,
1065 FALSE),
1067 HOWTO (R_sub,
1071 FALSE,
1073 complain_overflow_dont,
1074 bfin_oper_reloc,
1075 "R_expst_sub",
1076 FALSE,
1079 FALSE),
1081 HOWTO (R_mult,
1085 FALSE,
1087 complain_overflow_dont,
1088 bfin_oper_reloc,
1089 "R_expst_mult",
1090 FALSE,
1093 FALSE),
1095 HOWTO (R_div, /* type. */
1096 0, /* rightshift. */
1097 0, /* size (0 = byte, 1 = short, 2 = long). */
1098 0, /* bitsize. */
1099 FALSE, /* pc_relative. */
1100 0, /* bitpos. */
1101 complain_overflow_dont, /* complain_on_overflow. */
1102 bfin_oper_reloc, /* special_function. */
1103 "R_expst_div", /* name. */
1104 FALSE, /* partial_inplace. */
1105 0, /* src_mask. */
1106 0, /* dst_mask. */
1107 FALSE), /* pcrel_offset. */
1109 HOWTO (R_mod, /* type. */
1110 0, /* rightshift. */
1111 0, /* size (0 = byte, 1 = short, 2 = long). */
1112 0, /* bitsize. */
1113 FALSE, /* pc_relative. */
1114 0, /* bitpos. */
1115 complain_overflow_dont, /* complain_on_overflow. */
1116 bfin_oper_reloc, /* special_function. */
1117 "R_expst_mod", /* name. */
1118 FALSE, /* partial_inplace. */
1119 0, /* src_mask. */
1120 0, /* dst_mask. */
1121 FALSE), /* pcrel_offset. */
1123 HOWTO (R_lshift, /* type. */
1124 0, /* rightshift. */
1125 0, /* size (0 = byte, 1 = short, 2 = long). */
1126 0, /* bitsize. */
1127 FALSE, /* pc_relative. */
1128 0, /* bitpos. */
1129 complain_overflow_dont, /* complain_on_overflow. */
1130 bfin_oper_reloc, /* special_function. */
1131 "R_expst_lshift", /* name. */
1132 FALSE, /* partial_inplace. */
1133 0, /* src_mask. */
1134 0, /* dst_mask. */
1135 FALSE), /* pcrel_offset. */
1137 HOWTO (R_rshift, /* type. */
1138 0, /* rightshift. */
1139 0, /* size (0 = byte, 1 = short, 2 = long). */
1140 0, /* bitsize. */
1141 FALSE, /* pc_relative. */
1142 0, /* bitpos. */
1143 complain_overflow_dont, /* complain_on_overflow. */
1144 bfin_oper_reloc, /* special_function. */
1145 "R_expst_rshift", /* name. */
1146 FALSE, /* partial_inplace. */
1147 0, /* src_mask. */
1148 0, /* dst_mask. */
1149 FALSE), /* pcrel_offset. */
1151 HOWTO (R_and, /* type. */
1152 0, /* rightshift. */
1153 0, /* size (0 = byte, 1 = short, 2 = long). */
1154 0, /* bitsize. */
1155 FALSE, /* pc_relative. */
1156 0, /* bitpos. */
1157 complain_overflow_dont, /* complain_on_overflow. */
1158 bfin_oper_reloc, /* special_function. */
1159 "R_expst_and", /* name. */
1160 FALSE, /* partial_inplace. */
1161 0, /* src_mask. */
1162 0, /* dst_mask. */
1163 FALSE), /* pcrel_offset. */
1165 HOWTO (R_or, /* type. */
1166 0, /* rightshift. */
1167 0, /* size (0 = byte, 1 = short, 2 = long). */
1168 0, /* bitsize. */
1169 FALSE, /* pc_relative. */
1170 0, /* bitpos. */
1171 complain_overflow_dont, /* complain_on_overflow. */
1172 bfin_oper_reloc, /* special_function. */
1173 "R_expst_or", /* name. */
1174 FALSE, /* partial_inplace. */
1175 0, /* src_mask. */
1176 0, /* dst_mask. */
1177 FALSE), /* pcrel_offset. */
1179 HOWTO (R_xor, /* type. */
1180 0, /* rightshift. */
1181 0, /* size (0 = byte, 1 = short, 2 = long). */
1182 0, /* bitsize. */
1183 FALSE, /* pc_relative. */
1184 0, /* bitpos. */
1185 complain_overflow_dont, /* complain_on_overflow. */
1186 bfin_oper_reloc, /* special_function. */
1187 "R_expst_xor", /* name. */
1188 FALSE, /* partial_inplace. */
1189 0, /* src_mask. */
1190 0, /* dst_mask. */
1191 FALSE), /* pcrel_offset. */
1193 HOWTO (R_land, /* type. */
1194 0, /* rightshift. */
1195 0, /* size (0 = byte, 1 = short, 2 = long). */
1196 0, /* bitsize. */
1197 FALSE, /* pc_relative. */
1198 0, /* bitpos. */
1199 complain_overflow_dont, /* complain_on_overflow. */
1200 bfin_oper_reloc, /* special_function. */
1201 "R_expst_land", /* name. */
1202 FALSE, /* partial_inplace. */
1203 0, /* src_mask. */
1204 0, /* dst_mask. */
1205 FALSE), /* pcrel_offset. */
1207 HOWTO (R_lor, /* type. */
1208 0, /* rightshift. */
1209 0, /* size (0 = byte, 1 = short, 2 = long). */
1210 0, /* bitsize. */
1211 FALSE, /* pc_relative. */
1212 0, /* bitpos. */
1213 complain_overflow_dont, /* complain_on_overflow. */
1214 bfin_oper_reloc, /* special_function. */
1215 "R_expst_lor", /* name. */
1216 FALSE, /* partial_inplace. */
1217 0, /* src_mask. */
1218 0, /* dst_mask. */
1219 FALSE), /* pcrel_offset. */
1221 HOWTO (R_len, /* type. */
1222 0, /* rightshift. */
1223 0, /* size (0 = byte, 1 = short, 2 = long). */
1224 0, /* bitsize. */
1225 FALSE, /* pc_relative. */
1226 0, /* bitpos. */
1227 complain_overflow_dont, /* complain_on_overflow. */
1228 bfin_oper_reloc, /* special_function. */
1229 "R_expst_len", /* name. */
1230 FALSE, /* partial_inplace. */
1231 0, /* src_mask. */
1232 0, /* dst_mask. */
1233 FALSE), /* pcrel_offset. */
1235 HOWTO (R_neg, /* type. */
1236 0, /* rightshift. */
1237 0, /* size (0 = byte, 1 = short, 2 = long). */
1238 0, /* bitsize. */
1239 FALSE, /* pc_relative. */
1240 0, /* bitpos. */
1241 complain_overflow_dont, /* complain_on_overflow. */
1242 bfin_oper_reloc, /* special_function. */
1243 "R_expst_neg", /* name. */
1244 FALSE, /* partial_inplace. */
1245 0, /* src_mask. */
1246 0, /* dst_mask. */
1247 FALSE), /* pcrel_offset. */
1249 HOWTO (R_comp, /* type. */
1250 0, /* rightshift. */
1251 0, /* size (0 = byte, 1 = short, 2 = long). */
1252 0, /* bitsize. */
1253 FALSE, /* pc_relative. */
1254 0, /* bitpos. */
1255 complain_overflow_dont, /* complain_on_overflow. */
1256 bfin_oper_reloc, /* special_function. */
1257 "R_expst_comp", /* name. */
1258 FALSE, /* partial_inplace. */
1259 0, /* src_mask. */
1260 0, /* dst_mask. */
1261 FALSE), /* pcrel_offset. */
1263 HOWTO (R_page, /* type. */
1264 0, /* rightshift. */
1265 0, /* size (0 = byte, 1 = short, 2 = long). */
1266 0, /* bitsize. */
1267 FALSE, /* pc_relative. */
1268 0, /* bitpos. */
1269 complain_overflow_dont, /* complain_on_overflow. */
1270 bfin_oper_reloc, /* special_function. */
1271 "R_expst_page", /* name. */
1272 FALSE, /* partial_inplace. */
1273 0, /* src_mask. */
1274 0, /* dst_mask. */
1275 FALSE), /* pcrel_offset. */
1277 HOWTO (R_hwpage, /* type. */
1278 0, /* rightshift. */
1279 0, /* size (0 = byte, 1 = short, 2 = long). */
1280 0, /* bitsize. */
1281 FALSE, /* pc_relative. */
1282 0, /* bitpos. */
1283 complain_overflow_dont, /* complain_on_overflow. */
1284 bfin_oper_reloc, /* special_function. */
1285 "R_expst_hwpage", /* name. */
1286 FALSE, /* partial_inplace. */
1287 0, /* src_mask. */
1288 0, /* dst_mask. */
1289 FALSE), /* pcrel_offset. */
1291 HOWTO (R_addr, /* type. */
1292 0, /* rightshift. */
1293 0, /* size (0 = byte, 1 = short, 2 = long). */
1294 0, /* bitsize. */
1295 FALSE, /* pc_relative. */
1296 0, /* bitpos. */
1297 complain_overflow_dont, /* complain_on_overflow. */
1298 bfin_oper_reloc, /* special_function. */
1299 "R_expst_addr", /* name. */
1300 FALSE, /* partial_inplace. */
1301 0, /* src_mask. */
1302 0, /* dst_mask. */
1303 FALSE), /* pcrel_offset. */
1306 static reloc_howto_type bfin_gnuext_howto_table [] =
1308 HOWTO (R_pltpc, /* type. */
1309 0, /* rightshift. */
1310 1, /* size (0 = byte, 1 = short, 2 = long). */
1311 16, /* bitsize. */
1312 FALSE, /* pc_relative. */
1313 0, /* bitpos. */
1314 complain_overflow_bitfield, /* complain_on_overflow. */
1315 bfin_pltpc_reloc, /* special_function. */
1316 "R_pltpc", /* name. */
1317 FALSE, /* partial_inplace. */
1318 0xffff, /* src_mask. */
1319 0xffff, /* dst_mask. */
1320 FALSE), /* pcrel_offset. */
1322 HOWTO (R_got, /* type. */
1323 0, /* rightshift. */
1324 1, /* size (0 = byte, 1 = short, 2 = long). */
1325 16, /* bitsize. */
1326 FALSE, /* pc_relative. */
1327 0, /* bitpos. */
1328 complain_overflow_bitfield, /* complain_on_overflow. */
1329 bfd_elf_generic_reloc, /* special_function. */
1330 "R_got", /* name. */
1331 FALSE, /* partial_inplace. */
1332 0x7fff, /* src_mask. */
1333 0x7fff, /* dst_mask. */
1334 FALSE), /* pcrel_offset. */
1336 /* GNU extension to record C++ vtable hierarchy. */
1337 HOWTO (R_BFIN_GNU_VTINHERIT, /* type. */
1338 0, /* rightshift. */
1339 2, /* size (0 = byte, 1 = short, 2 = long). */
1340 0, /* bitsize. */
1341 FALSE, /* pc_relative. */
1342 0, /* bitpos. */
1343 complain_overflow_dont, /* complain_on_overflow. */
1344 NULL, /* special_function. */
1345 "R_BFIN_GNU_VTINHERIT", /* name. */
1346 FALSE, /* partial_inplace. */
1347 0, /* src_mask. */
1348 0, /* dst_mask. */
1349 FALSE), /* pcrel_offset. */
1351 /* GNU extension to record C++ vtable member usage. */
1352 HOWTO (R_BFIN_GNU_VTENTRY, /* type. */
1353 0, /* rightshift. */
1354 2, /* size (0 = byte, 1 = short, 2 = long). */
1355 0, /* bitsize. */
1356 FALSE, /* pc_relative. */
1357 0, /* bitpos. */
1358 complain_overflow_dont, /* complain_on_overflow. */
1359 _bfd_elf_rel_vtable_reloc_fn, /* special_function. */
1360 "R_BFIN_GNU_VTENTRY", /* name. */
1361 FALSE, /* partial_inplace. */
1362 0, /* src_mask. */
1363 0, /* dst_mask. */
1364 FALSE) /* pcrel_offset. */
1367 struct bfin_reloc_map
1369 bfd_reloc_code_real_type bfd_reloc_val;
1370 unsigned int bfin_reloc_val;
1373 static const struct bfin_reloc_map bfin_reloc_map [] =
1375 { BFD_RELOC_NONE, R_unused0 },
1376 { BFD_RELOC_BFIN_5_PCREL, R_pcrel5m2 },
1377 { BFD_RELOC_NONE, R_unused1 },
1378 { BFD_RELOC_BFIN_10_PCREL, R_pcrel10 },
1379 { BFD_RELOC_BFIN_12_PCREL_JUMP, R_pcrel12_jump },
1380 { BFD_RELOC_BFIN_16_IMM, R_rimm16 },
1381 { BFD_RELOC_BFIN_16_LOW, R_luimm16 },
1382 { BFD_RELOC_BFIN_16_HIGH, R_huimm16 },
1383 { BFD_RELOC_BFIN_12_PCREL_JUMP_S, R_pcrel12_jump_s },
1384 { BFD_RELOC_24_PCREL, R_pcrel24 },
1385 { BFD_RELOC_24_PCREL, R_pcrel24 },
1386 { BFD_RELOC_BFIN_24_PCREL_JUMP_L, R_pcrel24_jump_l },
1387 { BFD_RELOC_NONE, R_unusedb },
1388 { BFD_RELOC_NONE, R_unusedc },
1389 { BFD_RELOC_BFIN_24_PCREL_CALL_X, R_pcrel24_call_x },
1390 { BFD_RELOC_8, R_byte_data },
1391 { BFD_RELOC_16, R_byte2_data },
1392 { BFD_RELOC_32, R_byte4_data },
1393 { BFD_RELOC_BFIN_11_PCREL, R_pcrel11 },
1394 { BFD_RELOC_BFIN_GOT, R_got },
1395 { BFD_RELOC_BFIN_PLTPC, R_pltpc },
1396 { BFD_RELOC_VTABLE_INHERIT, R_BFIN_GNU_VTINHERIT },
1397 { BFD_RELOC_VTABLE_ENTRY, R_BFIN_GNU_VTENTRY },
1398 { BFD_ARELOC_BFIN_PUSH, R_push },
1399 { BFD_ARELOC_BFIN_CONST, R_const },
1400 { BFD_ARELOC_BFIN_ADD, R_add },
1401 { BFD_ARELOC_BFIN_SUB, R_sub },
1402 { BFD_ARELOC_BFIN_MULT, R_mult },
1403 { BFD_ARELOC_BFIN_DIV, R_div },
1404 { BFD_ARELOC_BFIN_MOD, R_mod },
1405 { BFD_ARELOC_BFIN_LSHIFT, R_lshift },
1406 { BFD_ARELOC_BFIN_RSHIFT, R_rshift },
1407 { BFD_ARELOC_BFIN_AND, R_and },
1408 { BFD_ARELOC_BFIN_OR, R_or },
1409 { BFD_ARELOC_BFIN_XOR, R_xor },
1410 { BFD_ARELOC_BFIN_LAND, R_land },
1411 { BFD_ARELOC_BFIN_LOR, R_lor },
1412 { BFD_ARELOC_BFIN_LEN, R_len },
1413 { BFD_ARELOC_BFIN_NEG, R_neg },
1414 { BFD_ARELOC_BFIN_COMP, R_comp },
1415 { BFD_ARELOC_BFIN_PAGE, R_page },
1416 { BFD_ARELOC_BFIN_HWPAGE, R_hwpage },
1417 { BFD_ARELOC_BFIN_ADDR, R_addr }
1422 static void
1423 bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
1424 arelent *cache_ptr,
1425 Elf_Internal_Rela *dst)
1427 unsigned int r_type;
1429 r_type = ELF32_R_TYPE (dst->r_info);
1431 if (r_type <= BFIN_RELOC_MAX)
1432 cache_ptr->howto = &bfin_howto_table [r_type];
1434 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1435 cache_ptr->howto = &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1437 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1438 cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1440 else
1441 cache_ptr->howto = (reloc_howto_type *) NULL;
1444 /* Given a BFD reloc type, return the howto. */
1445 static reloc_howto_type *
1446 bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1447 bfd_reloc_code_real_type code)
1449 unsigned int i;
1450 unsigned int r_type = BFIN_RELOC_MIN;
1452 for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
1453 if (bfin_reloc_map[i].bfd_reloc_val == code)
1454 r_type = bfin_reloc_map[i].bfin_reloc_val;
1456 if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
1457 return &bfin_howto_table [r_type];
1459 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1460 return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1462 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1463 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1465 return (reloc_howto_type *) NULL;
1468 /* Given a bfin relocation type, return the howto. */
1469 static reloc_howto_type *
1470 bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1471 unsigned int r_type)
1473 if (r_type <= BFIN_RELOC_MAX)
1474 return &bfin_howto_table [r_type];
1476 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1477 return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1479 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1480 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1482 return (reloc_howto_type *) NULL;
1486 /* Return TRUE if the name is a local label.
1487 bfin local labels begin with L$. */
1488 static bfd_boolean
1489 bfin_is_local_label_name (
1490 bfd *abfd ATTRIBUTE_UNUSED,
1491 const char *label)
1493 if (label[0] == 'L' && label[1] == '$' )
1494 return TRUE;
1496 return _bfd_elf_is_local_label_name (abfd, label);
1500 /* Look through the relocs for a section during the first phase, and
1501 allocate space in the global offset table or procedure linkage
1502 table. */
1504 static bfd_boolean
1505 bfin_check_relocs (bfd * abfd,
1506 struct bfd_link_info *info,
1507 asection *sec,
1508 const Elf_Internal_Rela *relocs)
1510 bfd *dynobj;
1511 Elf_Internal_Shdr *symtab_hdr;
1512 struct elf_link_hash_entry **sym_hashes;
1513 bfd_signed_vma *local_got_refcounts;
1514 const Elf_Internal_Rela *rel;
1515 const Elf_Internal_Rela *rel_end;
1516 asection *sgot;
1517 asection *srelgot;
1518 asection *sreloc;
1519 if (info->relocatable)
1520 return TRUE;
1522 dynobj = elf_hash_table (info)->dynobj;
1523 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1524 sym_hashes = elf_sym_hashes (abfd);
1525 local_got_refcounts = elf_local_got_refcounts (abfd);
1527 sgot = NULL;
1528 srelgot = NULL;
1529 sreloc = NULL;
1531 rel_end = relocs + sec->reloc_count;
1532 for (rel = relocs; rel < rel_end; rel++)
1534 unsigned long r_symndx;
1535 struct elf_link_hash_entry *h;
1537 r_symndx = ELF32_R_SYM (rel->r_info);
1538 if (r_symndx < symtab_hdr->sh_info)
1539 h = NULL;
1540 else
1541 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1543 switch (ELF32_R_TYPE (rel->r_info))
1545 /* This relocation describes the C++ object vtable hierarchy.
1546 Reconstruct it for later use during GC. */
1547 case R_BFIN_GNU_VTINHERIT:
1548 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1549 return FALSE;
1550 break;
1552 /* This relocation describes which C++ vtable entries
1553 are actually used. Record for later use during GC. */
1554 case R_BFIN_GNU_VTENTRY:
1555 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1556 return FALSE;
1557 break;
1559 case R_got:
1560 if (h != NULL
1561 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1562 break;
1563 /* Fall through. */
1565 if (dynobj == NULL)
1567 /* Create the .got section. */
1568 elf_hash_table (info)->dynobj = dynobj = abfd;
1569 if (!_bfd_elf_create_got_section (dynobj, info))
1570 return FALSE;
1573 if (sgot == NULL)
1575 sgot = bfd_get_section_by_name (dynobj, ".got");
1576 BFD_ASSERT (sgot != NULL);
1579 if (srelgot == NULL && (h != NULL || info->shared))
1581 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1582 if (srelgot == NULL)
1584 srelgot = bfd_make_section (dynobj, ".rela.got");
1585 if (srelgot == NULL
1586 || !bfd_set_section_flags (dynobj, srelgot,
1587 (SEC_ALLOC
1588 | SEC_LOAD
1589 | SEC_HAS_CONTENTS
1590 | SEC_IN_MEMORY
1591 | SEC_LINKER_CREATED
1592 | SEC_READONLY))
1593 || !bfd_set_section_alignment (dynobj, srelgot, 2))
1594 return FALSE;
1598 if (h != NULL)
1600 if (h->got.refcount == 0)
1602 /* Make sure this symbol is output as a dynamic symbol. */
1603 if (h->dynindx == -1 && !h->forced_local)
1605 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1606 return FALSE;
1609 /* Allocate space in the .got section. */
1610 sgot->size += 4;
1611 /* Allocate relocation space. */
1612 srelgot->size += sizeof (Elf32_External_Rela);
1614 h->got.refcount++;
1616 else
1618 /* This is a global offset table entry for a local symbol. */
1619 if (local_got_refcounts == NULL)
1621 bfd_size_type size;
1623 size = symtab_hdr->sh_info;
1624 size *= sizeof (bfd_signed_vma);
1625 local_got_refcounts = ((bfd_signed_vma *)
1626 bfd_zalloc (abfd, size));
1627 if (local_got_refcounts == NULL)
1628 return FALSE;
1629 elf_local_got_refcounts (abfd) = local_got_refcounts;
1631 if (local_got_refcounts[r_symndx] == 0)
1633 sgot->size += 4;
1634 if (info->shared)
1636 /* If we are generating a shared object, we need to
1637 output a R_68K_RELATIVE reloc so that the dynamic
1638 linker can adjust this GOT entry. */
1639 srelgot->size += sizeof (Elf32_External_Rela);
1642 local_got_refcounts[r_symndx]++;
1644 break;
1646 default:
1647 break;
1651 return TRUE;
1654 static enum elf_reloc_type_class
1655 elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
1657 switch ((int) ELF32_R_TYPE (rela->r_info))
1659 default:
1660 return reloc_class_normal;
1663 static bfd_boolean
1664 bfin_relocate_section (bfd * output_bfd,
1665 struct bfd_link_info *info,
1666 bfd * input_bfd,
1667 asection * input_section,
1668 bfd_byte * contents,
1669 Elf_Internal_Rela * relocs,
1670 Elf_Internal_Sym * local_syms,
1671 asection ** local_sections)
1673 bfd *dynobj;
1674 Elf_Internal_Shdr *symtab_hdr;
1675 struct elf_link_hash_entry **sym_hashes;
1676 bfd_vma *local_got_offsets;
1677 asection *sgot;
1678 asection *sreloc;
1679 Elf_Internal_Rela *rel;
1680 Elf_Internal_Rela *relend;
1681 char *error_msg = NULL;
1682 int i = 0;
1684 if (info->relocatable)
1685 return TRUE;
1687 dynobj = elf_hash_table (info)->dynobj;
1688 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1689 sym_hashes = elf_sym_hashes (input_bfd);
1690 local_got_offsets = elf_local_got_offsets (input_bfd);
1692 sgot = NULL;
1693 sreloc = NULL;
1695 rel = relocs;
1696 relend = relocs + input_section->reloc_count;
1697 for (; rel < relend; rel++, i++)
1699 int r_type;
1700 reloc_howto_type *howto;
1701 unsigned long r_symndx;
1702 struct elf_link_hash_entry *h;
1703 Elf_Internal_Sym *sym;
1704 asection *sec;
1705 bfd_vma relocation = 0;
1706 bfd_boolean unresolved_reloc;
1707 bfd_reloc_status_type r;
1709 r_type = ELF32_R_TYPE (rel->r_info);
1710 if (r_type < 0 || r_type >= 243)
1712 bfd_set_error (bfd_error_bad_value);
1713 return FALSE;
1716 if (r_type == R_BFIN_GNU_VTENTRY
1717 || r_type == R_BFIN_GNU_VTINHERIT)
1718 continue;
1720 howto = bfin_reloc_type_lookup (input_bfd, r_type);
1721 if (howto == NULL)
1723 bfd_set_error (bfd_error_bad_value);
1724 return FALSE;
1726 r_symndx = ELF32_R_SYM (rel->r_info);
1728 h = NULL;
1729 sym = NULL;
1730 sec = NULL;
1731 unresolved_reloc = FALSE;
1733 if (r_symndx < symtab_hdr->sh_info)
1735 sym = local_syms + r_symndx;
1736 sec = local_sections[r_symndx];
1737 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1738 /* Call to bfd_elf_rela_local_sym would have CHANGED the sec
1739 as well as updated relocation. The value returned is
1740 w.r.t the original section. */
1741 sec = local_sections[r_symndx];
1743 else
1745 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1747 while (h->root.type == bfd_link_hash_indirect
1748 || h->root.type == bfd_link_hash_warning)
1749 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1751 if (!
1752 (!strcmp (h->root.root.string, ".__constant")
1753 || !strcmp (h->root.root.string, ".__operator")))
1755 bfd_boolean warned;
1756 h = NULL;
1757 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1758 r_symndx, symtab_hdr, sym_hashes,
1759 h, sec, relocation,
1760 unresolved_reloc, warned);
1765 switch (r_type)
1767 case R_BFIN_GNU_VTINHERIT:
1768 case R_BFIN_GNU_VTENTRY:
1769 return bfd_reloc_ok;
1771 case R_got:
1772 /* Relocation is to the address of the entry for this symbol
1773 in the global offset table. */
1774 if (h != NULL
1775 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1776 break;
1777 /* Fall through. */
1778 /* Relocation is the offset of the entry for this symbol in
1779 the global offset table. */
1782 bfd_vma off;
1784 if (sgot == NULL)
1786 sgot = bfd_get_section_by_name (dynobj, ".got");
1787 BFD_ASSERT (sgot != NULL);
1790 if (h != NULL)
1792 bfd_boolean dyn;
1794 off = h->got.offset;
1795 BFD_ASSERT (off != (bfd_vma) - 1);
1797 dyn = elf_hash_table (info)->dynamic_sections_created;
1798 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
1799 || (info->shared
1800 && (info->symbolic
1801 || h->dynindx == -1
1802 || h->forced_local) && h->def_regular))
1804 /* This is actually a static link, or it is a
1805 -Bsymbolic link and the symbol is defined
1806 locally, or the symbol was forced to be local
1807 because of a version file.. We must initialize
1808 this entry in the global offset table. Since
1809 the offset must always be a multiple of 4, we
1810 use the least significant bit to record whether
1811 we have initialized it already.
1813 When doing a dynamic link, we create a .rela.got
1814 relocation entry to initialize the value. This
1815 is done in the finish_dynamic_symbol routine. */
1816 if ((off & 1) != 0)
1817 off &= ~1;
1818 else
1820 bfd_put_32 (output_bfd, relocation,
1821 sgot->contents + off);
1822 h->got.offset |= 1;
1825 else
1826 unresolved_reloc = FALSE;
1828 else
1830 BFD_ASSERT (local_got_offsets != NULL
1831 && local_got_offsets[r_symndx] != (bfd_vma) - 1);
1833 off = local_got_offsets[r_symndx];
1835 /* The offset must always be a multiple of 4. We use
1836 the least significant bit to record whether we have
1837 already generated the necessary reloc. */
1838 if ((off & 1) != 0)
1839 off &= ~1;
1840 else
1843 bfd_put_32 (output_bfd, relocation, sgot->contents + off);
1845 if (info->shared)
1847 asection *s;
1848 Elf_Internal_Rela outrel;
1849 bfd_byte *loc;
1851 s = bfd_get_section_by_name (dynobj, ".rela.got");
1852 BFD_ASSERT (s != NULL);
1854 outrel.r_offset = (sgot->output_section->vma
1855 + sgot->output_offset + off);
1856 outrel.r_info =
1857 ELF32_R_INFO (0, R_pcrel24);
1858 outrel.r_addend = relocation;
1859 loc = s->contents;
1860 loc +=
1861 s->reloc_count++ * sizeof (Elf32_External_Rela);
1862 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1865 local_got_offsets[r_symndx] |= 1;
1869 relocation = sgot->output_offset + off;
1870 rel->r_addend = 0;
1871 /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
1872 relocation /= 4;
1874 break;
1876 default:
1877 if (howto->special_function)
1879 bfd_reloc_status_type cont;
1880 arelent reloc_ent;
1881 asymbol symbol;
1882 asymbol *symbol1;
1883 symbol.flags = 0;
1884 symbol.section = bfd_und_section_ptr;
1885 symbol.value = 0;
1887 if (h != NULL)
1889 if (unresolved_reloc)
1891 break;
1893 if (h->root.type != bfd_link_hash_undefweak
1894 && h->root.type != bfd_link_hash_undefined)
1896 symbol.the_bfd = input_bfd;
1897 symbol.section = h->root.u.def.section;
1898 symbol.name = h->root.root.string;
1899 symbol.value = h->root.u.def.value;
1901 if (h->root.type == bfd_link_hash_defweak
1902 || h->root.type == bfd_link_hash_undefweak)
1904 symbol.name = h->root.root.string;
1905 symbol.flags |= BSF_WEAK;
1908 else
1910 symbol = *sec->symbol;
1912 reloc_ent.address = rel->r_offset;
1913 reloc_ent.howto = howto;
1914 reloc_ent.addend = rel->r_addend;
1915 symbol1 = &symbol;
1916 reloc_ent.sym_ptr_ptr = &symbol1;
1918 cont =
1919 howto->special_function (input_bfd, &reloc_ent, &symbol,
1920 contents, input_section,
1921 info->
1922 relocatable ? output_bfd : NULL,
1923 &error_msg);
1924 if (cont == bfd_reloc_ok)
1926 continue;
1929 else
1931 fprintf (stderr, "%s no special func r_type is %d\n",
1932 input_bfd->filename, r_type);
1933 bfd_set_error (bfd_error_bad_value);
1934 return FALSE;
1936 break;
1939 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
1940 because such sections are not SEC_ALLOC and thus ld.so will
1941 not process them. */
1942 if (unresolved_reloc
1943 && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
1945 (*_bfd_error_handler)
1946 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
1947 input_bfd,
1948 input_section, (long) rel->r_offset, h->root.root.string);
1949 return FALSE;
1952 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1953 contents, rel->r_offset,
1954 relocation, rel->r_addend);
1956 if (r != bfd_reloc_ok)
1958 const char *name;
1960 if (h != NULL)
1961 name = h->root.root.string;
1962 else
1964 name = bfd_elf_string_from_elf_section (input_bfd,
1965 symtab_hdr->sh_link,
1966 sym->st_name);
1967 if (name == NULL)
1968 return FALSE;
1969 if (*name == '\0')
1970 name = bfd_section_name (input_bfd, sec);
1973 if (r == bfd_reloc_overflow)
1975 if (!(info->callbacks->reloc_overflow
1976 (info, (h ? &h->root : NULL), name, howto->name,
1977 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
1978 return FALSE;
1980 else
1982 (*_bfd_error_handler)
1983 (_("%B(%A+0x%lx): reloc against `%s': error %d"),
1984 input_bfd, input_section,
1985 (long) rel->r_offset, name, (int) r);
1986 return FALSE;
1991 return TRUE;
1994 static asection *
1995 bfin_gc_mark_hook (asection * sec,
1996 struct bfd_link_info *info ATTRIBUTE_UNUSED,
1997 Elf_Internal_Rela * rel,
1998 struct elf_link_hash_entry *h,
1999 Elf_Internal_Sym * sym)
2001 if (h != NULL)
2003 switch (ELF32_R_TYPE (rel->r_info))
2006 case R_BFIN_GNU_VTINHERIT:
2007 case R_BFIN_GNU_VTENTRY:
2008 break;
2010 default:
2011 switch (h->root.type)
2013 default:
2014 break;
2016 case bfd_link_hash_defined:
2017 case bfd_link_hash_defweak:
2018 return h->root.u.def.section;
2020 case bfd_link_hash_common:
2021 return h->root.u.c.p->section;
2025 else
2026 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
2028 return NULL;
2032 /* Update the got entry reference counts for the section being removed. */
2034 static bfd_boolean
2035 bfin_gc_sweep_hook (bfd * abfd,
2036 struct bfd_link_info *info,
2037 asection * sec,
2038 const Elf_Internal_Rela * relocs)
2040 Elf_Internal_Shdr *symtab_hdr;
2041 struct elf_link_hash_entry **sym_hashes;
2042 bfd_signed_vma *local_got_refcounts;
2043 const Elf_Internal_Rela *rel, *relend;
2044 bfd *dynobj;
2045 asection *sgot;
2046 asection *srelgot;
2048 dynobj = elf_hash_table (info)->dynobj;
2049 if (dynobj == NULL)
2050 return TRUE;
2052 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2053 sym_hashes = elf_sym_hashes (abfd);
2054 local_got_refcounts = elf_local_got_refcounts (abfd);
2056 sgot = bfd_get_section_by_name (dynobj, ".got");
2057 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
2059 relend = relocs + sec->reloc_count;
2060 for (rel = relocs; rel < relend; rel++)
2062 unsigned long r_symndx;
2063 struct elf_link_hash_entry *h;
2065 switch (ELF32_R_TYPE (rel->r_info))
2067 case R_got:
2068 r_symndx = ELF32_R_SYM (rel->r_info);
2069 if (r_symndx >= symtab_hdr->sh_info)
2071 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2072 if (h->got.refcount > 0)
2074 --h->got.refcount;
2075 if (h->got.refcount == 0)
2077 /* We don't need the .got entry any more. */
2078 sgot->size -= 4;
2079 srelgot->size -= sizeof (Elf32_External_Rela);
2083 else if (local_got_refcounts != NULL)
2085 if (local_got_refcounts[r_symndx] > 0)
2087 --local_got_refcounts[r_symndx];
2088 if (local_got_refcounts[r_symndx] == 0)
2090 /* We don't need the .got entry any more. */
2091 sgot->size -= 4;
2092 if (info->shared)
2093 srelgot->size -= sizeof (Elf32_External_Rela);
2097 break;
2098 default:
2099 break;
2103 return TRUE;
2107 /* Merge backend specific data from an object file to the output
2108 object file when linking. */
2109 static bfd_boolean
2110 elf32_bfin_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
2112 flagword out_flags;
2113 flagword in_flags;
2115 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2116 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
2117 return TRUE;
2119 in_flags = elf_elfheader (ibfd)->e_flags;
2120 out_flags = elf_elfheader (obfd)->e_flags;
2122 if (!elf_flags_init (obfd))
2124 elf_flags_init (obfd) = TRUE;
2125 elf_elfheader (obfd)->e_flags = in_flags;
2128 return TRUE;
2132 static bfd_boolean
2133 elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
2135 elf_elfheader (abfd)->e_flags = flags;
2136 elf_flags_init (abfd) = TRUE;
2137 return TRUE;
2141 /* Display the flags field. */
2142 static bfd_boolean
2143 elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
2145 FILE *file = (FILE *) ptr;
2147 BFD_ASSERT (abfd != NULL && ptr != NULL);
2149 /* Print normal ELF private data. */
2150 _bfd_elf_print_private_bfd_data (abfd, ptr);
2152 /* Ignore init flag - it may not be set, despite the flags field
2153 containing valid data. */
2155 /* xgettext:c-format */
2156 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
2158 fputc ('\n', file);
2160 return TRUE;
2163 /* bfin ELF linker hash entry. */
2165 struct bfin_link_hash_entry
2167 struct elf_link_hash_entry root;
2169 /* Number of PC relative relocs copied for this symbol. */
2170 struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
2173 /* bfin ELF linker hash table. */
2175 struct bfin_link_hash_table
2177 struct elf_link_hash_table root;
2179 /* Small local sym to section mapping cache. */
2180 struct sym_sec_cache sym_sec;
2183 #define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
2185 static struct bfd_hash_entry *
2186 bfin_link_hash_newfunc (struct bfd_hash_entry *entry,
2187 struct bfd_hash_table *table, const char *string)
2189 struct bfd_hash_entry *ret = entry;
2191 /* Allocate the structure if it has not already been allocated by a
2192 subclass. */
2193 if (ret == NULL)
2194 ret = bfd_hash_allocate (table, sizeof (struct bfin_link_hash_entry));
2195 if (ret == NULL)
2196 return ret;
2198 /* Call the allocation method of the superclass. */
2199 ret = _bfd_elf_link_hash_newfunc (ret, table, string);
2200 if (ret != NULL)
2201 bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;
2203 return ret;
2206 /* Create an bfin ELF linker hash table. */
2208 static struct bfd_link_hash_table *
2209 bfin_link_hash_table_create (bfd * abfd)
2211 struct bfin_link_hash_table *ret;
2212 bfd_size_type amt = sizeof (struct bfin_link_hash_table);
2214 ret = (struct bfin_link_hash_table *) bfd_malloc (amt);
2215 if (ret == (struct bfin_link_hash_table *) NULL)
2216 return NULL;
2218 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
2219 bfin_link_hash_newfunc))
2221 free (ret);
2222 return NULL;
2225 ret->sym_sec.abfd = NULL;
2227 return &ret->root.root;
2230 /* The size in bytes of an entry in the procedure linkage table. */
2232 /* Finish up the dynamic sections. */
2234 static bfd_boolean
2235 bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
2236 struct bfd_link_info *info)
2238 bfd *dynobj;
2239 asection *sdyn;
2241 dynobj = elf_hash_table (info)->dynobj;
2243 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
2245 if (elf_hash_table (info)->dynamic_sections_created)
2247 Elf32_External_Dyn *dyncon, *dynconend;
2249 BFD_ASSERT (sdyn != NULL);
2251 dyncon = (Elf32_External_Dyn *) sdyn->contents;
2252 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2253 for (; dyncon < dynconend; dyncon++)
2255 Elf_Internal_Dyn dyn;
2257 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2262 return TRUE;
2265 /* Finish up dynamic symbol handling. We set the contents of various
2266 dynamic sections here. */
2268 static bfd_boolean
2269 bfin_finish_dynamic_symbol (bfd * output_bfd,
2270 struct bfd_link_info *info,
2271 struct elf_link_hash_entry *h,
2272 Elf_Internal_Sym * sym)
2274 bfd *dynobj;
2276 dynobj = elf_hash_table (info)->dynobj;
2278 if (h->got.offset != (bfd_vma) - 1)
2280 asection *sgot;
2281 asection *srela;
2282 Elf_Internal_Rela rela;
2283 bfd_byte *loc;
2285 /* This symbol has an entry in the global offset table.
2286 Set it up. */
2288 sgot = bfd_get_section_by_name (dynobj, ".got");
2289 srela = bfd_get_section_by_name (dynobj, ".rela.got");
2290 BFD_ASSERT (sgot != NULL && srela != NULL);
2292 rela.r_offset = (sgot->output_section->vma
2293 + sgot->output_offset
2294 + (h->got.offset & ~(bfd_vma) 1));
2296 /* If this is a -Bsymbolic link, and the symbol is defined
2297 locally, we just want to emit a RELATIVE reloc. Likewise if
2298 the symbol was forced to be local because of a version file.
2299 The entry in the global offset table will already have been
2300 initialized in the relocate_section function. */
2301 if (info->shared
2302 && (info->symbolic
2303 || h->dynindx == -1 || h->forced_local) && h->def_regular)
2305 fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
2306 rela.r_info = ELF32_R_INFO (0, R_pcrel24);
2307 rela.r_addend = bfd_get_signed_32 (output_bfd,
2308 (sgot->contents
2310 (h->got.
2311 offset & ~(bfd_vma) 1)));
2313 else
2315 bfd_put_32 (output_bfd, (bfd_vma) 0,
2316 sgot->contents + (h->got.offset & ~(bfd_vma) 1));
2317 rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
2318 rela.r_addend = 0;
2321 loc = srela->contents;
2322 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
2323 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2326 if (h->needs_copy)
2328 BFD_ASSERT (0);
2330 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2331 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2332 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2333 sym->st_shndx = SHN_ABS;
2335 return TRUE;
2338 /* Adjust a symbol defined by a dynamic object and referenced by a
2339 regular object. The current definition is in some section of the
2340 dynamic object, but we're not including those sections. We have to
2341 change the definition to something the rest of the link can
2342 understand. */
2344 static bfd_boolean
2345 bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
2346 struct elf_link_hash_entry *h)
2348 bfd *dynobj;
2349 asection *s;
2350 unsigned int power_of_two;
2352 dynobj = elf_hash_table (info)->dynobj;
2354 /* Make sure we know what is going on here. */
2355 BFD_ASSERT (dynobj != NULL
2356 && (h->needs_plt
2357 || h->u.weakdef != NULL
2358 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2360 /* If this is a function, put it in the procedure linkage table. We
2361 will fill in the contents of the procedure linkage table later,
2362 when we know the address of the .got section. */
2363 if (h->type == STT_FUNC || h->needs_plt)
2365 BFD_ASSERT(0);
2368 /* If this is a weak symbol, and there is a real definition, the
2369 processor independent code will have arranged for us to see the
2370 real definition first, and we can just use the same value. */
2371 if (h->u.weakdef != NULL)
2373 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2374 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2375 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2376 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2377 return TRUE;
2380 /* This is a reference to a symbol defined by a dynamic object which
2381 is not a function. */
2383 /* If we are creating a shared library, we must presume that the
2384 only references to the symbol are via the global offset table.
2385 For such cases we need not do anything here; the relocations will
2386 be handled correctly by relocate_section. */
2387 if (info->shared)
2388 return TRUE;
2390 /* We must allocate the symbol in our .dynbss section, which will
2391 become part of the .bss section of the executable. There will be
2392 an entry for this symbol in the .dynsym section. The dynamic
2393 object will contain position independent code, so all references
2394 from the dynamic object to this symbol will go through the global
2395 offset table. The dynamic linker will use the .dynsym entry to
2396 determine the address it must put in the global offset table, so
2397 both the dynamic object and the regular object will refer to the
2398 same memory location for the variable. */
2400 s = bfd_get_section_by_name (dynobj, ".dynbss");
2401 BFD_ASSERT (s != NULL);
2403 /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
2404 copy the initial value out of the dynamic object and into the
2405 runtime process image. We need to remember the offset into the
2406 .rela.bss section we are going to use. */
2407 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2409 asection *srel;
2411 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2412 BFD_ASSERT (srel != NULL);
2413 srel->size += sizeof (Elf32_External_Rela);
2414 h->needs_copy = 1;
2417 /* We need to figure out the alignment required for this symbol. I
2418 have no idea how ELF linkers handle this. */
2419 power_of_two = bfd_log2 (h->size);
2420 if (power_of_two > 3)
2421 power_of_two = 3;
2423 /* Apply the required alignment. */
2424 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2425 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2427 if (!bfd_set_section_alignment (dynobj, s, power_of_two))
2428 return FALSE;
2431 /* Define the symbol as being at this point in the section. */
2432 h->root.u.def.section = s;
2433 h->root.u.def.value = s->size;
2435 /* Increment the section size to make room for the symbol. */
2436 s->size += h->size;
2438 return TRUE;
2441 /* The bfin linker needs to keep track of the number of relocs that it
2442 decides to copy in check_relocs for each symbol. This is so that it
2443 can discard PC relative relocs if it doesn't need them when linking
2444 with -Bsymbolic. We store the information in a field extending the
2445 regular ELF linker hash table. */
2447 /* This structure keeps track of the number of PC relative relocs we have
2448 copied for a given symbol. */
2450 struct bfin_pcrel_relocs_copied
2452 /* Next section. */
2453 struct bfin_pcrel_relocs_copied *next;
2454 /* A section in dynobj. */
2455 asection *section;
2456 /* Number of relocs copied in this section. */
2457 bfd_size_type count;
2460 /* This function is called via elf_link_hash_traverse if we are
2461 creating a shared object. In the -Bsymbolic case it discards the
2462 space allocated to copy PC relative relocs against symbols which
2463 are defined in regular objects. For the normal shared case, it
2464 discards space for pc-relative relocs that have become local due to
2465 symbol visibility changes. We allocated space for them in the
2466 check_relocs routine, but we won't fill them in in the
2467 relocate_section routine.
2469 We also check whether any of the remaining relocations apply
2470 against a readonly section, and set the DF_TEXTREL flag in this
2471 case. */
2473 static bfd_boolean
2474 bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
2476 struct bfd_link_info *info = (struct bfd_link_info *) inf;
2477 struct bfin_pcrel_relocs_copied *s;
2479 if (h->root.type == bfd_link_hash_warning)
2480 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2482 if (!h->def_regular || (!info->symbolic && !h->forced_local))
2484 if ((info->flags & DF_TEXTREL) == 0)
2486 /* Look for relocations against read-only sections. */
2487 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
2488 s != NULL; s = s->next)
2489 if ((s->section->flags & SEC_READONLY) != 0)
2491 info->flags |= DF_TEXTREL;
2492 break;
2496 return TRUE;
2499 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
2500 s != NULL; s = s->next)
2501 s->section->size -= s->count * sizeof (Elf32_External_Rela);
2503 return TRUE;
2506 /* Set the sizes of the dynamic sections. */
2507 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
2509 static bfd_boolean
2510 bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
2511 struct bfd_link_info *info)
2513 bfd *dynobj;
2514 asection *s;
2515 bfd_boolean relocs;
2517 dynobj = elf_hash_table (info)->dynobj;
2518 BFD_ASSERT (dynobj != NULL);
2520 if (elf_hash_table (info)->dynamic_sections_created)
2522 /* Set the contents of the .interp section to the interpreter. */
2523 if (info->executable)
2525 s = bfd_get_section_by_name (dynobj, ".interp");
2526 BFD_ASSERT (s != NULL);
2527 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2528 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2531 else
2533 /* We may have created entries in the .rela.got section.
2534 However, if we are not creating the dynamic sections, we will
2535 not actually use these entries. Reset the size of .rela.got,
2536 which will cause it to get stripped from the output file
2537 below. */
2538 s = bfd_get_section_by_name (dynobj, ".rela.got");
2539 if (s != NULL)
2540 s->size = 0;
2543 /* If this is a -Bsymbolic shared link, then we need to discard all
2544 PC relative relocs against symbols defined in a regular object.
2545 For the normal shared case we discard the PC relative relocs
2546 against symbols that have become local due to visibility changes.
2547 We allocated space for them in the check_relocs routine, but we
2548 will not fill them in in the relocate_section routine. */
2549 if (info->shared)
2550 elf_link_hash_traverse (elf_hash_table (info),
2551 bfin_discard_copies, (PTR) info);
2553 /* The check_relocs and adjust_dynamic_symbol entry points have
2554 determined the sizes of the various dynamic sections. Allocate
2555 memory for them. */
2556 relocs = FALSE;
2557 for (s = dynobj->sections; s != NULL; s = s->next)
2559 const char *name;
2560 bfd_boolean strip;
2562 if ((s->flags & SEC_LINKER_CREATED) == 0)
2563 continue;
2565 /* It's OK to base decisions on the section name, because none
2566 of the dynobj section names depend upon the input files. */
2567 name = bfd_get_section_name (dynobj, s);
2569 strip = FALSE;
2571 if (strncmp (name, ".rela", 5) == 0)
2573 if (s->size == 0)
2575 /* If we don't need this section, strip it from the
2576 output file. This is mostly to handle .rela.bss and
2577 .rela.plt. We must create both sections in
2578 create_dynamic_sections, because they must be created
2579 before the linker maps input sections to output
2580 sections. The linker does that before
2581 adjust_dynamic_symbol is called, and it is that
2582 function which decides whether anything needs to go
2583 into these sections. */
2584 strip = TRUE;
2586 else
2588 relocs = TRUE;
2590 /* We use the reloc_count field as a counter if we need
2591 to copy relocs into the output file. */
2592 s->reloc_count = 0;
2595 else if (strncmp (name, ".got", 4) != 0)
2597 /* It's not one of our sections, so don't allocate space. */
2598 continue;
2601 if (strip)
2603 s->flags |= SEC_EXCLUDE;
2604 continue;
2607 /* Allocate memory for the section contents. */
2608 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
2609 Unused entries should be reclaimed before the section's contents
2610 are written out, but at the moment this does not happen. Thus in
2611 order to prevent writing out garbage, we initialise the section's
2612 contents to zero. */
2613 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2614 if (s->contents == NULL && s->size != 0)
2615 return FALSE;
2618 if (elf_hash_table (info)->dynamic_sections_created)
2620 /* Add some entries to the .dynamic section. We fill in the
2621 values later, in bfin_finish_dynamic_sections, but we
2622 must add the entries now so that we get the correct size for
2623 the .dynamic section. The DT_DEBUG entry is filled in by the
2624 dynamic linker and used by the debugger. */
2625 #define add_dynamic_entry(TAG, VAL) \
2626 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2628 if (!info->shared)
2630 if (!add_dynamic_entry (DT_DEBUG, 0))
2631 return FALSE;
2635 if (relocs)
2637 if (!add_dynamic_entry (DT_RELA, 0)
2638 || !add_dynamic_entry (DT_RELASZ, 0)
2639 || !add_dynamic_entry (DT_RELAENT,
2640 sizeof (Elf32_External_Rela)))
2641 return FALSE;
2644 if ((info->flags & DF_TEXTREL) != 0)
2646 if (!add_dynamic_entry (DT_TEXTREL, 0))
2647 return FALSE;
2650 #undef add_dynamic_entry
2652 return TRUE;
2655 /* Given a .data section and a .emreloc in-memory section, store
2656 relocation information into the .emreloc section which can be
2657 used at runtime to relocate the section. This is called by the
2658 linker when the --embedded-relocs switch is used. This is called
2659 after the add_symbols entry point has been called for all the
2660 objects, and before the final_link entry point is called. */
2662 bfd_boolean
2663 bfd_bfin_elf32_create_embedded_relocs (
2664 bfd *abfd,
2665 struct bfd_link_info *info,
2666 asection *datasec,
2667 asection *relsec,
2668 char **errmsg)
2670 Elf_Internal_Shdr *symtab_hdr;
2671 Elf_Internal_Sym *isymbuf = NULL;
2672 Elf_Internal_Rela *internal_relocs = NULL;
2673 Elf_Internal_Rela *irel, *irelend;
2674 bfd_byte *p;
2675 bfd_size_type amt;
2677 BFD_ASSERT (! info->relocatable);
2679 *errmsg = NULL;
2681 if (datasec->reloc_count == 0)
2682 return TRUE;
2684 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2686 /* Get a copy of the native relocations. */
2687 internal_relocs = (_bfd_elf_link_read_relocs
2688 (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
2689 info->keep_memory));
2690 if (internal_relocs == NULL)
2691 goto error_return;
2693 amt = (bfd_size_type) datasec->reloc_count * 12;
2694 relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2695 if (relsec->contents == NULL)
2696 goto error_return;
2698 p = relsec->contents;
2700 irelend = internal_relocs + datasec->reloc_count;
2701 for (irel = internal_relocs; irel < irelend; irel++, p += 12)
2703 asection *targetsec;
2705 /* We are going to write a four byte longword into the runtime
2706 reloc section. The longword will be the address in the data
2707 section which must be relocated. It is followed by the name
2708 of the target section NUL-padded or truncated to 8
2709 characters. */
2711 /* We can only relocate absolute longword relocs at run time. */
2712 if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
2714 *errmsg = _("unsupported reloc type");
2715 bfd_set_error (bfd_error_bad_value);
2716 goto error_return;
2719 /* Get the target section referred to by the reloc. */
2720 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2722 /* A local symbol. */
2723 Elf_Internal_Sym *isym;
2725 /* Read this BFD's local symbols if we haven't done so already. */
2726 if (isymbuf == NULL)
2728 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2729 if (isymbuf == NULL)
2730 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2731 symtab_hdr->sh_info, 0,
2732 NULL, NULL, NULL);
2733 if (isymbuf == NULL)
2734 goto error_return;
2737 isym = isymbuf + ELF32_R_SYM (irel->r_info);
2738 targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2740 else
2742 unsigned long indx;
2743 struct elf_link_hash_entry *h;
2745 /* An external symbol. */
2746 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2747 h = elf_sym_hashes (abfd)[indx];
2748 BFD_ASSERT (h != NULL);
2749 if (h->root.type == bfd_link_hash_defined
2750 || h->root.type == bfd_link_hash_defweak)
2751 targetsec = h->root.u.def.section;
2752 else
2753 targetsec = NULL;
2756 bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2757 memset (p + 4, 0, 8);
2758 if (targetsec != NULL)
2759 strncpy (p + 4, targetsec->output_section->name, 8);
2762 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2763 free (isymbuf);
2764 if (internal_relocs != NULL
2765 && elf_section_data (datasec)->relocs != internal_relocs)
2766 free (internal_relocs);
2767 return TRUE;
2769 error_return:
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 FALSE;
2778 #define TARGET_LITTLE_SYM bfd_elf32_bfin_vec
2779 #define TARGET_LITTLE_NAME "elf32-bfin"
2780 #define ELF_ARCH bfd_arch_bfin
2781 #define ELF_MACHINE_CODE EM_BLACKFIN
2782 #define ELF_MAXPAGESIZE 0x1000
2783 #define elf_symbol_leading_char '_'
2785 #define bfd_elf32_bfd_reloc_type_lookup bfin_bfd_reloc_type_lookup
2786 #define elf_info_to_howto bfin_info_to_howto
2787 #define elf_info_to_howto_rel 0
2789 #define bfd_elf32_bfd_is_local_label_name \
2790 bfin_is_local_label_name
2791 #define bfin_hash_table(p) \
2792 ((struct bfin_link_hash_table *) (p)->hash)
2796 #define elf_backend_create_dynamic_sections \
2797 _bfd_elf_create_dynamic_sections
2798 #define bfd_elf32_bfd_link_hash_table_create \
2799 bfin_link_hash_table_create
2800 #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
2802 #define elf_backend_check_relocs bfin_check_relocs
2803 #define elf_backend_adjust_dynamic_symbol \
2804 bfin_adjust_dynamic_symbol
2805 #define elf_backend_size_dynamic_sections \
2806 bfin_size_dynamic_sections
2807 #define elf_backend_relocate_section bfin_relocate_section
2808 #define elf_backend_finish_dynamic_symbol \
2809 bfin_finish_dynamic_symbol
2810 #define elf_backend_finish_dynamic_sections \
2811 bfin_finish_dynamic_sections
2812 #define elf_backend_gc_mark_hook bfin_gc_mark_hook
2813 #define elf_backend_gc_sweep_hook bfin_gc_sweep_hook
2814 #define bfd_elf32_bfd_merge_private_bfd_data \
2815 elf32_bfin_merge_private_bfd_data
2816 #define bfd_elf32_bfd_set_private_flags \
2817 elf32_bfin_set_private_flags
2818 #define bfd_elf32_bfd_print_private_bfd_data \
2819 elf32_bfin_print_private_bfd_data
2820 #define elf_backend_reloc_type_class elf32_bfin_reloc_type_class
2821 #define elf_backend_can_gc_sections 1
2822 #define elf_backend_can_refcount 1
2823 #define elf_backend_want_got_plt 0
2824 #define elf_backend_plt_readonly 1
2825 #define elf_backend_want_plt_sym 0
2826 #define elf_backend_got_header_size 12
2827 #define elf_backend_rela_normal 1
2830 #include "elf32-target.h"