1 /* ADI Blackfin BFD support for 32-bit ELF.
2 Copyright 2005, 2006 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,
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)
54 reloc_stack_push (bfd_vma value
)
56 reloc_stack
[reloc_stack_tos
++] = value
;
60 reloc_stack_pop (void)
62 return reloc_stack
[--reloc_stack_tos
];
66 reloc_stack_operate (unsigned int oper
)
74 reloc_stack
[reloc_stack_tos
- 2] + reloc_stack
[reloc_stack_tos
- 1];
81 reloc_stack
[reloc_stack_tos
- 2] - reloc_stack
[reloc_stack_tos
- 1];
88 reloc_stack
[reloc_stack_tos
- 2] * reloc_stack
[reloc_stack_tos
- 1];
94 if (reloc_stack
[reloc_stack_tos
- 1] == 0)
96 _bfd_abort (__FILE__
, __LINE__
, _("Division by zero. "));
101 reloc_stack
[reloc_stack_tos
- 2] / reloc_stack
[reloc_stack_tos
- 1];
102 reloc_stack_tos
-= 2;
109 reloc_stack
[reloc_stack_tos
- 2] % reloc_stack
[reloc_stack_tos
- 1];
110 reloc_stack_tos
-= 2;
116 reloc_stack
[reloc_stack_tos
- 2] << reloc_stack
[reloc_stack_tos
-
118 reloc_stack_tos
-= 2;
124 reloc_stack
[reloc_stack_tos
- 2] >> reloc_stack
[reloc_stack_tos
-
126 reloc_stack_tos
-= 2;
132 reloc_stack
[reloc_stack_tos
- 2] & reloc_stack
[reloc_stack_tos
- 1];
133 reloc_stack_tos
-= 2;
139 reloc_stack
[reloc_stack_tos
- 2] | reloc_stack
[reloc_stack_tos
- 1];
140 reloc_stack_tos
-= 2;
146 reloc_stack
[reloc_stack_tos
- 2] ^ reloc_stack
[reloc_stack_tos
- 1];
147 reloc_stack_tos
-= 2;
152 value
= reloc_stack
[reloc_stack_tos
- 2]
153 && reloc_stack
[reloc_stack_tos
- 1];
154 reloc_stack_tos
-= 2;
159 value
= reloc_stack
[reloc_stack_tos
- 2]
160 || reloc_stack
[reloc_stack_tos
- 1];
161 reloc_stack_tos
-= 2;
166 value
= -reloc_stack
[reloc_stack_tos
- 1];
172 value
= ~reloc_stack
[reloc_stack_tos
- 1];
173 reloc_stack_tos
-= 1;
178 fprintf (stderr
, "bfin relocation : Internal bug\n");
183 reloc_stack_push (value
);
188 /* FUNCTION : bfin_pltpc_reloc
189 ABSTRACT : TODO : figure out how to handle pltpc relocs. */
190 static bfd_reloc_status_type
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
;
205 static bfd_reloc_status_type
206 bfin_pcrel24_reloc (bfd
*abfd
,
207 arelent
*reloc_entry
,
210 asection
*input_section
,
212 char **error_message ATTRIBUTE_UNUSED
)
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();
228 if (bfd_is_und_section (symbol
->section
)
229 && (symbol
->flags
& BSF_WEAK
) == 0
231 return bfd_reloc_undefined
;
233 if (bfd_is_com_section (symbol
->section
))
236 relocation
= symbol
->value
;
238 output_section
= symbol
->section
->output_section
;
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
,
261 bfd_arch_bits_per_address(abfd
),
263 if (status
!= bfd_reloc_ok
)
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
;
281 reloc_entry
->address
+= input_section
->output_offset
;
282 reloc_entry
->addend
+= symbol
->section
->output_offset
;
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. */
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
);
307 static bfd_reloc_status_type
308 bfin_push_reloc (bfd
*abfd ATTRIBUTE_UNUSED
,
309 arelent
*reloc_entry
,
311 PTR data ATTRIBUTE_UNUSED
,
312 asection
*input_section
,
314 char **error_message ATTRIBUTE_UNUSED
)
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
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. */
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
;
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
);
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
,
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
);
372 reloc_entry
->address
+= input_section
->output_offset
;
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
,
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
);
392 reloc_entry
->address
+= input_section
->output_offset
;
397 static bfd_reloc_status_type
398 bfin_imm16_reloc (bfd
*abfd
,
399 arelent
*reloc_entry
,
402 asection
*input_section
,
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
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. */
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
;
441 relocation
= reloc_stack_pop ();
446 reloc_entry
->address
+= input_section
->output_offset
;
447 reloc_entry
->addend
+= symbol
->section
->output_offset
;
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
,
460 bfd_arch_bits_per_address(abfd
),
462 if (flag
!= bfd_reloc_ok
)
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
;
472 bfd_put_16 (abfd
, x
, (unsigned char *) data
+ reloc_addr
);
477 static bfd_reloc_status_type
478 bfin_byte4_reloc (bfd
*abfd
,
479 arelent
*reloc_entry
,
482 asection
*input_section
,
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
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. */
509 output_base
= output_section
->vma
;
512 && symbol
->section
->name
513 && !strcmp (symbol
->name
, symbol
->section
->name
))
516 relocation
+= output_base
+ symbol
->section
->output_offset
;
519 relocation
+= reloc_entry
->addend
;
523 relocation
= reloc_stack_pop();
524 relocation
+= reloc_entry
->addend
;
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
;
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;
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
);
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
,
556 asection
*input_section
,
558 char **error_message ATTRIBUTE_UNUSED
)
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
576 return bfd_reloc_undefined
;
578 /* Get symbol value. (Common symbols are special.) */
579 if (bfd_is_com_section (symbol
->section
))
582 relocation
= symbol
->value
;
584 output_section
= symbol
->section
->output_section
;
586 /* Convert input-section-relative symbol value to absolute. */
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
;
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
;
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
,
631 bfd_arch_bits_per_address(abfd
),
633 if (status
!= bfd_reloc_ok
)
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
;
651 x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
653 /* handle 8 and 16 bit relocations here. */
658 char x
= bfd_get_8 (abfd
, (char *) data
+ addr
);
660 bfd_put_8 (abfd
, x
, (unsigned char *) data
+ addr
);
666 unsigned short x
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ addr
);
668 bfd_put_16 (abfd
, (bfd_vma
) x
, (unsigned char *) data
+ addr
);
673 return bfd_reloc_other
;
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 *));
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. */
736 2, /* size (0 = byte, 1 = short, 2 = long). */
738 FALSE
, /* pc_relative. */
740 complain_overflow_bitfield
, /* complain_on_overflow. */
741 bfd_elf_generic_reloc
, /* special_function. */
742 "R_unused0", /* name. */
743 FALSE
, /* partial_inplace. */
746 FALSE
), /* pcrel_offset. */
748 HOWTO (R_pcrel5m2
, /* type. */
750 1, /* size (0 = byte, 1 = short, 2 = long).. */
752 TRUE
, /* pc_relative. */
754 complain_overflow_unsigned
, /* complain_on_overflow. */
755 bfin_bfd_reloc
, /* special_function. */
756 "R_pcrel5m2", /* name. */
757 FALSE
, /* partial_inplace. */
759 0x0000000F, /* dst_mask. */
760 FALSE
), /* pcrel_offset. */
762 HOWTO (R_unused1
, /* type. */
764 2, /* size (0 = byte, 1 = short, 2 = long). */
766 FALSE
, /* pc_relative. */
768 complain_overflow_bitfield
, /* complain_on_overflow. */
769 bfd_elf_generic_reloc
, /* special_function. */
770 "R_unused1", /* name. */
771 FALSE
, /* partial_inplace. */
774 FALSE
), /* pcrel_offset. */
776 HOWTO (R_pcrel10
, /* type. */
778 1, /* size (0 = byte, 1 = short, 2 = long). */
780 TRUE
, /* pc_relative. */
782 complain_overflow_signed
, /* complain_on_overflow. */
783 bfin_bfd_reloc
, /* special_function. */
784 "R_pcrel10", /* name. */
785 FALSE
, /* partial_inplace. */
787 0x000003FF, /* dst_mask. */
788 TRUE
), /* pcrel_offset. */
790 HOWTO (R_pcrel12_jump
, /* type. */
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). */
798 TRUE
, /* pc_relative. */
800 complain_overflow_signed
, /* complain_on_overflow. */
801 bfin_bfd_reloc
, /* special_function. */
802 "R_pcrel12_jump", /* name. */
803 FALSE
, /* partial_inplace. */
805 0x0FFF, /* dst_mask. */
806 TRUE
), /* pcrel_offset. */
808 HOWTO (R_rimm16
, /* type. */
810 1, /* size (0 = byte, 1 = short, 2 = long). */
812 FALSE
, /* pc_relative. */
814 complain_overflow_signed
, /* complain_on_overflow. */
815 bfin_imm16_reloc
, /* special_function. */
816 "R_rimm16", /* name. */
817 FALSE
, /* partial_inplace. */
819 0x0000FFFF, /* dst_mask. */
820 TRUE
), /* pcrel_offset. */
822 HOWTO (R_luimm16
, /* type. */
824 1, /* size (0 = byte, 1 = short, 2 = long). */
826 FALSE
, /* pc_relative. */
828 complain_overflow_dont
, /* complain_on_overflow. */
829 bfin_imm16_reloc
, /* special_function. */
830 "R_luimm16", /* name. */
831 FALSE
, /* partial_inplace. */
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). */
840 FALSE
, /* pc_relative. */
842 complain_overflow_unsigned
, /* complain_on_overflow. */
843 bfin_imm16_reloc
, /* special_function. */
844 "R_huimm16", /* name. */
845 FALSE
, /* partial_inplace. */
847 0x0000FFFF, /* dst_mask. */
848 TRUE
), /* pcrel_offset. */
850 HOWTO (R_pcrel12_jump_s
, /* type. */
852 1, /* size (0 = byte, 1 = short, 2 = long). */
854 TRUE
, /* pc_relative. */
856 complain_overflow_signed
, /* complain_on_overflow. */
857 bfin_bfd_reloc
, /* special_function. */
858 "R_pcrel12_jump_s", /* name. */
859 FALSE
, /* partial_inplace. */
861 0x00000FFF, /* dst_mask. */
862 TRUE
), /* pcrel_offset. */
864 HOWTO (R_pcrel24_jump_x
, /* type. */
866 2, /* size (0 = byte, 1 = short, 2 = long). */
868 TRUE
, /* pc_relative. */
870 complain_overflow_signed
, /* complain_on_overflow. */
871 bfin_pcrel24_reloc
, /* special_function. */
872 "R_pcrel24_jump_x", /* name. */
873 FALSE
, /* partial_inplace. */
875 0x00FFFFFF, /* dst_mask. */
876 TRUE
), /* pcrel_offset. */
878 HOWTO (R_pcrel24
, /* type. */
880 2, /* size (0 = byte, 1 = short, 2 = long). */
882 TRUE
, /* pc_relative. */
884 complain_overflow_signed
, /* complain_on_overflow. */
885 bfin_pcrel24_reloc
, /* special_function. */
886 "R_pcrel24", /* name. */
887 FALSE
, /* partial_inplace. */
889 0x00FFFFFF, /* dst_mask. */
890 TRUE
), /* pcrel_offset. */
892 HOWTO (R_unusedb
, /* type. */
894 2, /* size (0 = byte, 1 = short, 2 = long). */
896 FALSE
, /* pc_relative. */
898 complain_overflow_dont
, /* complain_on_overflow. */
899 bfd_elf_generic_reloc
, /* special_function. */
900 "R_unusedb", /* name. */
901 FALSE
, /* partial_inplace. */
904 FALSE
), /* pcrel_offset. */
906 HOWTO (R_unusedc
, /* type. */
908 2, /* size (0 = byte, 1 = short, 2 = long). */
910 FALSE
, /* pc_relative. */
912 complain_overflow_dont
, /* complain_on_overflow. */
913 bfd_elf_generic_reloc
, /* special_function. */
914 "R_unusedc", /* name. */
915 FALSE
, /* partial_inplace. */
918 FALSE
), /* pcrel_offset. */
920 HOWTO (R_pcrel24_jump_l
, /* type. */
922 2, /* size (0 = byte, 1 = short, 2 = long). */
924 TRUE
, /* pc_relative. */
926 complain_overflow_signed
, /* complain_on_overflow. */
927 bfin_pcrel24_reloc
, /* special_function. */
928 "R_pcrel24_jump_l", /* name. */
929 FALSE
, /* partial_inplace. */
931 0x00FFFFFF, /* dst_mask. */
932 TRUE
), /* pcrel_offset. */
934 HOWTO (R_pcrel24_call_x
, /* type. */
936 2, /* size (0 = byte, 1 = short, 2 = long). */
938 TRUE
, /* pc_relative. */
940 complain_overflow_signed
, /* complain_on_overflow. */
941 bfin_pcrel24_reloc
, /* special_function. */
942 "R_pcrel24_call_x", /* name. */
943 FALSE
, /* partial_inplace. */
945 0x00FFFFFF, /* dst_mask. */
946 TRUE
), /* pcrel_offset. */
948 HOWTO (R_var_eq_symb
, /* type. */
950 2, /* size (0 = byte, 1 = short, 2 = long). */
952 FALSE
, /* pc_relative. */
954 complain_overflow_bitfield
, /* complain_on_overflow. */
955 bfin_bfd_reloc
, /* special_function. */
956 "R_var_eq_symb", /* name. */
957 FALSE
, /* partial_inplace. */
960 FALSE
), /* pcrel_offset. */
962 HOWTO (R_byte_data
, /* type. */
964 0, /* size (0 = byte, 1 = short, 2 = long). */
966 FALSE
, /* pc_relative. */
968 complain_overflow_unsigned
, /* complain_on_overflow. */
969 bfin_bfd_reloc
, /* special_function. */
970 "R_byte_data", /* name. */
971 FALSE
, /* partial_inplace. */
973 0xFF, /* dst_mask. */
974 TRUE
), /* pcrel_offset. */
976 HOWTO (R_byte2_data
, /* type. */
978 1, /* size (0 = byte, 1 = short, 2 = long). */
980 FALSE
, /* pc_relative. */
982 complain_overflow_signed
, /* complain_on_overflow. */
983 bfin_bfd_reloc
, /* special_function. */
984 "R_byte2_data", /* name. */
985 FALSE
, /* partial_inplace. */
987 0xFFFF, /* dst_mask. */
988 TRUE
), /* pcrel_offset. */
990 HOWTO (R_byte4_data
, /* type. */
992 2, /* size (0 = byte, 1 = short, 2 = long). */
994 FALSE
, /* pc_relative. */
996 complain_overflow_unsigned
, /* complain_on_overflow. */
997 bfin_byte4_reloc
, /* special_function. */
998 "R_byte4_data", /* name. */
999 FALSE
, /* partial_inplace. */
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). */
1008 TRUE
, /* pc_relative. */
1010 complain_overflow_unsigned
, /* complain_on_overflow. */
1011 bfin_bfd_reloc
, /* special_function. */
1012 "R_pcrel11", /* name. */
1013 FALSE
, /* partial_inplace. */
1015 0x000003FF, /* dst_mask. */
1016 FALSE
), /* pcrel_offset. */
1019 static reloc_howto_type bfin_areloc_howto_table
[] =
1027 complain_overflow_dont
,
1041 complain_overflow_dont
,
1055 complain_overflow_dont
,
1069 complain_overflow_dont
,
1083 complain_overflow_dont
,
1091 HOWTO (R_div
, /* type. */
1092 0, /* rightshift. */
1093 0, /* size (0 = byte, 1 = short, 2 = long). */
1095 FALSE
, /* pc_relative. */
1097 complain_overflow_dont
, /* complain_on_overflow. */
1098 bfin_oper_reloc
, /* special_function. */
1099 "R_expst_div", /* name. */
1100 FALSE
, /* partial_inplace. */
1103 FALSE
), /* pcrel_offset. */
1105 HOWTO (R_mod
, /* type. */
1106 0, /* rightshift. */
1107 0, /* size (0 = byte, 1 = short, 2 = long). */
1109 FALSE
, /* pc_relative. */
1111 complain_overflow_dont
, /* complain_on_overflow. */
1112 bfin_oper_reloc
, /* special_function. */
1113 "R_expst_mod", /* name. */
1114 FALSE
, /* partial_inplace. */
1117 FALSE
), /* pcrel_offset. */
1119 HOWTO (R_lshift
, /* type. */
1120 0, /* rightshift. */
1121 0, /* size (0 = byte, 1 = short, 2 = long). */
1123 FALSE
, /* pc_relative. */
1125 complain_overflow_dont
, /* complain_on_overflow. */
1126 bfin_oper_reloc
, /* special_function. */
1127 "R_expst_lshift", /* name. */
1128 FALSE
, /* partial_inplace. */
1131 FALSE
), /* pcrel_offset. */
1133 HOWTO (R_rshift
, /* type. */
1134 0, /* rightshift. */
1135 0, /* size (0 = byte, 1 = short, 2 = long). */
1137 FALSE
, /* pc_relative. */
1139 complain_overflow_dont
, /* complain_on_overflow. */
1140 bfin_oper_reloc
, /* special_function. */
1141 "R_expst_rshift", /* name. */
1142 FALSE
, /* partial_inplace. */
1145 FALSE
), /* pcrel_offset. */
1147 HOWTO (R_and
, /* type. */
1148 0, /* rightshift. */
1149 0, /* size (0 = byte, 1 = short, 2 = long). */
1151 FALSE
, /* pc_relative. */
1153 complain_overflow_dont
, /* complain_on_overflow. */
1154 bfin_oper_reloc
, /* special_function. */
1155 "R_expst_and", /* name. */
1156 FALSE
, /* partial_inplace. */
1159 FALSE
), /* pcrel_offset. */
1161 HOWTO (R_or
, /* type. */
1162 0, /* rightshift. */
1163 0, /* size (0 = byte, 1 = short, 2 = long). */
1165 FALSE
, /* pc_relative. */
1167 complain_overflow_dont
, /* complain_on_overflow. */
1168 bfin_oper_reloc
, /* special_function. */
1169 "R_expst_or", /* name. */
1170 FALSE
, /* partial_inplace. */
1173 FALSE
), /* pcrel_offset. */
1175 HOWTO (R_xor
, /* type. */
1176 0, /* rightshift. */
1177 0, /* size (0 = byte, 1 = short, 2 = long). */
1179 FALSE
, /* pc_relative. */
1181 complain_overflow_dont
, /* complain_on_overflow. */
1182 bfin_oper_reloc
, /* special_function. */
1183 "R_expst_xor", /* name. */
1184 FALSE
, /* partial_inplace. */
1187 FALSE
), /* pcrel_offset. */
1189 HOWTO (R_land
, /* type. */
1190 0, /* rightshift. */
1191 0, /* size (0 = byte, 1 = short, 2 = long). */
1193 FALSE
, /* pc_relative. */
1195 complain_overflow_dont
, /* complain_on_overflow. */
1196 bfin_oper_reloc
, /* special_function. */
1197 "R_expst_land", /* name. */
1198 FALSE
, /* partial_inplace. */
1201 FALSE
), /* pcrel_offset. */
1203 HOWTO (R_lor
, /* type. */
1204 0, /* rightshift. */
1205 0, /* size (0 = byte, 1 = short, 2 = long). */
1207 FALSE
, /* pc_relative. */
1209 complain_overflow_dont
, /* complain_on_overflow. */
1210 bfin_oper_reloc
, /* special_function. */
1211 "R_expst_lor", /* name. */
1212 FALSE
, /* partial_inplace. */
1215 FALSE
), /* pcrel_offset. */
1217 HOWTO (R_len
, /* type. */
1218 0, /* rightshift. */
1219 0, /* size (0 = byte, 1 = short, 2 = long). */
1221 FALSE
, /* pc_relative. */
1223 complain_overflow_dont
, /* complain_on_overflow. */
1224 bfin_oper_reloc
, /* special_function. */
1225 "R_expst_len", /* name. */
1226 FALSE
, /* partial_inplace. */
1229 FALSE
), /* pcrel_offset. */
1231 HOWTO (R_neg
, /* type. */
1232 0, /* rightshift. */
1233 0, /* size (0 = byte, 1 = short, 2 = long). */
1235 FALSE
, /* pc_relative. */
1237 complain_overflow_dont
, /* complain_on_overflow. */
1238 bfin_oper_reloc
, /* special_function. */
1239 "R_expst_neg", /* name. */
1240 FALSE
, /* partial_inplace. */
1243 FALSE
), /* pcrel_offset. */
1245 HOWTO (R_comp
, /* type. */
1246 0, /* rightshift. */
1247 0, /* size (0 = byte, 1 = short, 2 = long). */
1249 FALSE
, /* pc_relative. */
1251 complain_overflow_dont
, /* complain_on_overflow. */
1252 bfin_oper_reloc
, /* special_function. */
1253 "R_expst_comp", /* name. */
1254 FALSE
, /* partial_inplace. */
1257 FALSE
), /* pcrel_offset. */
1259 HOWTO (R_page
, /* type. */
1260 0, /* rightshift. */
1261 0, /* size (0 = byte, 1 = short, 2 = long). */
1263 FALSE
, /* pc_relative. */
1265 complain_overflow_dont
, /* complain_on_overflow. */
1266 bfin_oper_reloc
, /* special_function. */
1267 "R_expst_page", /* name. */
1268 FALSE
, /* partial_inplace. */
1271 FALSE
), /* pcrel_offset. */
1273 HOWTO (R_hwpage
, /* type. */
1274 0, /* rightshift. */
1275 0, /* size (0 = byte, 1 = short, 2 = long). */
1277 FALSE
, /* pc_relative. */
1279 complain_overflow_dont
, /* complain_on_overflow. */
1280 bfin_oper_reloc
, /* special_function. */
1281 "R_expst_hwpage", /* name. */
1282 FALSE
, /* partial_inplace. */
1285 FALSE
), /* pcrel_offset. */
1287 HOWTO (R_addr
, /* type. */
1288 0, /* rightshift. */
1289 0, /* size (0 = byte, 1 = short, 2 = long). */
1291 FALSE
, /* pc_relative. */
1293 complain_overflow_dont
, /* complain_on_overflow. */
1294 bfin_oper_reloc
, /* special_function. */
1295 "R_expst_addr", /* name. */
1296 FALSE
, /* partial_inplace. */
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). */
1308 FALSE
, /* pc_relative. */
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). */
1322 FALSE
, /* pc_relative. */
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). */
1337 FALSE
, /* pc_relative. */
1339 complain_overflow_dont
, /* complain_on_overflow. */
1340 NULL
, /* special_function. */
1341 "R_BFIN_GNU_VTINHERIT", /* name. */
1342 FALSE
, /* partial_inplace. */
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). */
1352 FALSE
, /* pc_relative. */
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. */
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
}
1419 bfin_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
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
];
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
)
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$. */
1485 bfin_is_local_label_name (
1486 bfd
*abfd ATTRIBUTE_UNUSED
,
1489 if (label
[0] == 'L' && label
[1] == '$' )
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
1501 bfin_check_relocs (bfd
* abfd
,
1502 struct bfd_link_info
*info
,
1504 const Elf_Internal_Rela
*relocs
)
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
;
1515 if (info
->relocatable
)
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
);
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
)
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
))
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
))
1557 && strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
1563 /* Create the .got section. */
1564 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
1565 if (!_bfd_elf_create_got_section (dynobj
, info
))
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");
1582 || !bfd_set_section_flags (dynobj
, srelgot
,
1587 | SEC_LINKER_CREATED
1589 || !bfd_set_section_alignment (dynobj
, srelgot
, 2))
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
))
1605 /* Allocate space in the .got section. */
1607 /* Allocate relocation space. */
1608 srelgot
->size
+= sizeof (Elf32_External_Rela
);
1614 /* This is a global offset table entry for a local symbol. */
1615 if (local_got_refcounts
== NULL
)
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
)
1625 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
1627 if (local_got_refcounts
[r_symndx
] == 0)
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
]++;
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
))
1656 return reloc_class_normal
;
1661 bfin_relocate_section (bfd
* output_bfd
,
1662 struct bfd_link_info
*info
,
1664 asection
* input_section
,
1665 bfd_byte
* contents
,
1666 Elf_Internal_Rela
* relocs
,
1667 Elf_Internal_Sym
* local_syms
,
1668 asection
** local_sections
)
1671 Elf_Internal_Shdr
*symtab_hdr
;
1672 struct elf_link_hash_entry
**sym_hashes
;
1673 bfd_vma
*local_got_offsets
;
1676 Elf_Internal_Rela
*rel
;
1677 Elf_Internal_Rela
*relend
;
1680 if (info
->relocatable
)
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
);
1692 relend
= relocs
+ input_section
->reloc_count
;
1693 for (; rel
< relend
; rel
++, i
++)
1696 reloc_howto_type
*howto
;
1697 unsigned long r_symndx
;
1698 struct elf_link_hash_entry
*h
;
1699 Elf_Internal_Sym
*sym
;
1701 bfd_vma relocation
= 0;
1702 bfd_boolean unresolved_reloc
;
1703 bfd_reloc_status_type r
;
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
);
1713 if (r_type
== R_BFIN_GNU_VTENTRY
1714 || r_type
== R_BFIN_GNU_VTINHERIT
)
1717 howto
= bfin_reloc_type_lookup (input_bfd
, r_type
);
1720 bfd_set_error (bfd_error_bad_value
);
1723 r_symndx
= ELF32_R_SYM (rel
->r_info
);
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
);
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
;
1745 (!strcmp (h
->root
.root
.string
, ".__constant")
1746 || !strcmp (h
->root
.root
.string
, ".__operator")))
1750 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1751 r_symndx
, symtab_hdr
, sym_hashes
,
1753 unresolved_reloc
, warned
);
1758 address
= rel
->r_offset
;
1759 /* First, get stack relocs out of the way. */
1763 reloc_stack_push (relocation
+ rel
->r_addend
);
1767 reloc_stack_push (rel
->r_addend
);
1786 reloc_stack_operate (r_type
);
1791 if (!is_reloc_stack_empty())
1792 relocation
= reloc_stack_pop ();
1796 /* Then, process normally. */
1799 case R_BFIN_GNU_VTINHERIT
:
1800 case R_BFIN_GNU_VTENTRY
:
1801 return bfd_reloc_ok
;
1804 /* Relocation is to the address of the entry for this symbol
1805 in the global offset table. */
1807 && strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
1810 /* Relocation is the offset of the entry for this symbol in
1811 the global offset table. */
1818 sgot
= bfd_get_section_by_name (dynobj
, ".got");
1819 BFD_ASSERT (sgot
!= NULL
);
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
)
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. */
1853 bfd_put_32 (output_bfd
, relocation
,
1854 sgot
->contents
+ off
);
1859 unresolved_reloc
= FALSE
;
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. */
1874 bfd_put_32 (output_bfd
, relocation
, sgot
->contents
+ off
);
1879 Elf_Internal_Rela outrel
;
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
);
1888 ELF32_R_INFO (0, R_pcrel24
);
1889 outrel
.r_addend
= relocation
;
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
;
1902 /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
1908 case R_pcrel24_jump_l
:
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. */
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);
1943 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1945 relocation
, rel
->r_addend
);
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'"),
1960 input_section
, (long) rel
->r_offset
, h
->root
.root
.string
);
1964 if (r
!= bfd_reloc_ok
)
1969 name
= h
->root
.root
.string
;
1972 name
= bfd_elf_string_from_elf_section (input_bfd
,
1973 symtab_hdr
->sh_link
,
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
)))
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
);
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
)
2011 switch (ELF32_R_TYPE (rel
->r_info
))
2014 case R_BFIN_GNU_VTINHERIT
:
2015 case R_BFIN_GNU_VTENTRY
:
2019 switch (h
->root
.type
)
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
;
2034 return bfd_section_from_elf_index (sec
->owner
, sym
->st_shndx
);
2040 /* Update the got entry reference counts for the section being removed. */
2043 bfin_gc_sweep_hook (bfd
* abfd
,
2044 struct bfd_link_info
*info
,
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
;
2056 dynobj
= elf_hash_table (info
)->dynobj
;
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
))
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)
2083 if (h
->got
.refcount
== 0)
2085 /* We don't need the .got entry any more. */
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. */
2101 srelgot
->size
-= sizeof (Elf32_External_Rela
);
2115 /* Merge backend specific data from an object file to the output
2116 object file when linking. */
2118 elf32_bfin_merge_private_bfd_data (bfd
* ibfd
, bfd
* obfd
)
2123 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
2124 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
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
;
2141 elf32_bfin_set_private_flags (bfd
* abfd
, flagword flags
)
2143 elf_elfheader (abfd
)->e_flags
= flags
;
2144 elf_flags_init (abfd
) = TRUE
;
2149 /* Display the flags field. */
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
);
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
2202 ret
= bfd_hash_allocate (table
, sizeof (struct bfin_link_hash_entry
));
2206 /* Call the allocation method of the superclass. */
2207 ret
= _bfd_elf_link_hash_newfunc (ret
, table
, string
);
2209 bfin_hash_entry (ret
)->pcrel_relocs_copied
= NULL
;
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
)
2226 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
2227 bfin_link_hash_newfunc
,
2228 sizeof (struct bfin_link_hash_entry
)))
2234 ret
->sym_sec
.abfd
= NULL
;
2236 return &ret
->root
.root
;
2239 /* The size in bytes of an entry in the procedure linkage table. */
2241 /* Finish up the dynamic sections. */
2244 bfin_finish_dynamic_sections (bfd
* output_bfd ATTRIBUTE_UNUSED
,
2245 struct bfd_link_info
*info
)
2250 dynobj
= elf_hash_table (info
)->dynobj
;
2252 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
2254 if (elf_hash_table (info
)->dynamic_sections_created
)
2256 Elf32_External_Dyn
*dyncon
, *dynconend
;
2258 BFD_ASSERT (sdyn
!= NULL
);
2260 dyncon
= (Elf32_External_Dyn
*) sdyn
->contents
;
2261 dynconend
= (Elf32_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
2262 for (; dyncon
< dynconend
; dyncon
++)
2264 Elf_Internal_Dyn dyn
;
2266 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &dyn
);
2274 /* Finish up dynamic symbol handling. We set the contents of various
2275 dynamic sections here. */
2278 bfin_finish_dynamic_symbol (bfd
* output_bfd
,
2279 struct bfd_link_info
*info
,
2280 struct elf_link_hash_entry
*h
,
2281 Elf_Internal_Sym
* sym
)
2285 dynobj
= elf_hash_table (info
)->dynobj
;
2287 if (h
->got
.offset
!= (bfd_vma
) - 1)
2291 Elf_Internal_Rela rela
;
2294 /* This symbol has an entry in the global offset table.
2297 sgot
= bfd_get_section_by_name (dynobj
, ".got");
2298 srela
= bfd_get_section_by_name (dynobj
, ".rela.got");
2299 BFD_ASSERT (sgot
!= NULL
&& srela
!= NULL
);
2301 rela
.r_offset
= (sgot
->output_section
->vma
2302 + sgot
->output_offset
2303 + (h
->got
.offset
& ~(bfd_vma
) 1));
2305 /* If this is a -Bsymbolic link, and the symbol is defined
2306 locally, we just want to emit a RELATIVE reloc. Likewise if
2307 the symbol was forced to be local because of a version file.
2308 The entry in the global offset table will already have been
2309 initialized in the relocate_section function. */
2312 || h
->dynindx
== -1 || h
->forced_local
) && h
->def_regular
)
2314 fprintf(stderr
, "*** check this relocation %s\n", __FUNCTION__
);
2315 rela
.r_info
= ELF32_R_INFO (0, R_pcrel24
);
2316 rela
.r_addend
= bfd_get_signed_32 (output_bfd
,
2320 offset
& ~(bfd_vma
) 1)));
2324 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
2325 sgot
->contents
+ (h
->got
.offset
& ~(bfd_vma
) 1));
2326 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_got
);
2330 loc
= srela
->contents
;
2331 loc
+= srela
->reloc_count
++ * sizeof (Elf32_External_Rela
);
2332 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
2339 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2340 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
2341 || h
== elf_hash_table (info
)->hgot
)
2342 sym
->st_shndx
= SHN_ABS
;
2347 /* Adjust a symbol defined by a dynamic object and referenced by a
2348 regular object. The current definition is in some section of the
2349 dynamic object, but we're not including those sections. We have to
2350 change the definition to something the rest of the link can
2354 bfin_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2355 struct elf_link_hash_entry
*h
)
2359 unsigned int power_of_two
;
2361 dynobj
= elf_hash_table (info
)->dynobj
;
2363 /* Make sure we know what is going on here. */
2364 BFD_ASSERT (dynobj
!= NULL
2366 || h
->u
.weakdef
!= NULL
2367 || (h
->def_dynamic
&& h
->ref_regular
&& !h
->def_regular
)));
2369 /* If this is a function, put it in the procedure linkage table. We
2370 will fill in the contents of the procedure linkage table later,
2371 when we know the address of the .got section. */
2372 if (h
->type
== STT_FUNC
|| h
->needs_plt
)
2377 /* If this is a weak symbol, and there is a real definition, the
2378 processor independent code will have arranged for us to see the
2379 real definition first, and we can just use the same value. */
2380 if (h
->u
.weakdef
!= NULL
)
2382 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
2383 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
2384 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
2385 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
2389 /* This is a reference to a symbol defined by a dynamic object which
2390 is not a function. */
2392 /* If we are creating a shared library, we must presume that the
2393 only references to the symbol are via the global offset table.
2394 For such cases we need not do anything here; the relocations will
2395 be handled correctly by relocate_section. */
2399 /* We must allocate the symbol in our .dynbss section, which will
2400 become part of the .bss section of the executable. There will be
2401 an entry for this symbol in the .dynsym section. The dynamic
2402 object will contain position independent code, so all references
2403 from the dynamic object to this symbol will go through the global
2404 offset table. The dynamic linker will use the .dynsym entry to
2405 determine the address it must put in the global offset table, so
2406 both the dynamic object and the regular object will refer to the
2407 same memory location for the variable. */
2409 s
= bfd_get_section_by_name (dynobj
, ".dynbss");
2410 BFD_ASSERT (s
!= NULL
);
2412 /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
2413 copy the initial value out of the dynamic object and into the
2414 runtime process image. We need to remember the offset into the
2415 .rela.bss section we are going to use. */
2416 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
2420 srel
= bfd_get_section_by_name (dynobj
, ".rela.bss");
2421 BFD_ASSERT (srel
!= NULL
);
2422 srel
->size
+= sizeof (Elf32_External_Rela
);
2426 /* We need to figure out the alignment required for this symbol. I
2427 have no idea how ELF linkers handle this. */
2428 power_of_two
= bfd_log2 (h
->size
);
2429 if (power_of_two
> 3)
2432 /* Apply the required alignment. */
2433 s
->size
= BFD_ALIGN (s
->size
, (bfd_size_type
) (1 << power_of_two
));
2434 if (power_of_two
> bfd_get_section_alignment (dynobj
, s
))
2436 if (!bfd_set_section_alignment (dynobj
, s
, power_of_two
))
2440 /* Define the symbol as being at this point in the section. */
2441 h
->root
.u
.def
.section
= s
;
2442 h
->root
.u
.def
.value
= s
->size
;
2444 /* Increment the section size to make room for the symbol. */
2450 /* The bfin linker needs to keep track of the number of relocs that it
2451 decides to copy in check_relocs for each symbol. This is so that it
2452 can discard PC relative relocs if it doesn't need them when linking
2453 with -Bsymbolic. We store the information in a field extending the
2454 regular ELF linker hash table. */
2456 /* This structure keeps track of the number of PC relative relocs we have
2457 copied for a given symbol. */
2459 struct bfin_pcrel_relocs_copied
2462 struct bfin_pcrel_relocs_copied
*next
;
2463 /* A section in dynobj. */
2465 /* Number of relocs copied in this section. */
2466 bfd_size_type count
;
2469 /* This function is called via elf_link_hash_traverse if we are
2470 creating a shared object. In the -Bsymbolic case it discards the
2471 space allocated to copy PC relative relocs against symbols which
2472 are defined in regular objects. For the normal shared case, it
2473 discards space for pc-relative relocs that have become local due to
2474 symbol visibility changes. We allocated space for them in the
2475 check_relocs routine, but we won't fill them in in the
2476 relocate_section routine.
2478 We also check whether any of the remaining relocations apply
2479 against a readonly section, and set the DF_TEXTREL flag in this
2483 bfin_discard_copies (struct elf_link_hash_entry
*h
, PTR inf
)
2485 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
2486 struct bfin_pcrel_relocs_copied
*s
;
2488 if (h
->root
.type
== bfd_link_hash_warning
)
2489 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2491 if (!h
->def_regular
|| (!info
->symbolic
&& !h
->forced_local
))
2493 if ((info
->flags
& DF_TEXTREL
) == 0)
2495 /* Look for relocations against read-only sections. */
2496 for (s
= bfin_hash_entry (h
)->pcrel_relocs_copied
;
2497 s
!= NULL
; s
= s
->next
)
2498 if ((s
->section
->flags
& SEC_READONLY
) != 0)
2500 info
->flags
|= DF_TEXTREL
;
2508 for (s
= bfin_hash_entry (h
)->pcrel_relocs_copied
;
2509 s
!= NULL
; s
= s
->next
)
2510 s
->section
->size
-= s
->count
* sizeof (Elf32_External_Rela
);
2515 /* Set the sizes of the dynamic sections. */
2516 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
2519 bfin_size_dynamic_sections (bfd
* output_bfd ATTRIBUTE_UNUSED
,
2520 struct bfd_link_info
*info
)
2526 dynobj
= elf_hash_table (info
)->dynobj
;
2527 BFD_ASSERT (dynobj
!= NULL
);
2529 if (elf_hash_table (info
)->dynamic_sections_created
)
2531 /* Set the contents of the .interp section to the interpreter. */
2532 if (info
->executable
)
2534 s
= bfd_get_section_by_name (dynobj
, ".interp");
2535 BFD_ASSERT (s
!= NULL
);
2536 s
->size
= sizeof ELF_DYNAMIC_INTERPRETER
;
2537 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
2542 /* We may have created entries in the .rela.got section.
2543 However, if we are not creating the dynamic sections, we will
2544 not actually use these entries. Reset the size of .rela.got,
2545 which will cause it to get stripped from the output file
2547 s
= bfd_get_section_by_name (dynobj
, ".rela.got");
2552 /* If this is a -Bsymbolic shared link, then we need to discard all
2553 PC relative relocs against symbols defined in a regular object.
2554 For the normal shared case we discard the PC relative relocs
2555 against symbols that have become local due to visibility changes.
2556 We allocated space for them in the check_relocs routine, but we
2557 will not fill them in in the relocate_section routine. */
2559 elf_link_hash_traverse (elf_hash_table (info
),
2560 bfin_discard_copies
, (PTR
) info
);
2562 /* The check_relocs and adjust_dynamic_symbol entry points have
2563 determined the sizes of the various dynamic sections. Allocate
2566 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
2571 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
2574 /* It's OK to base decisions on the section name, because none
2575 of the dynobj section names depend upon the input files. */
2576 name
= bfd_get_section_name (dynobj
, s
);
2580 if (strncmp (name
, ".rela", 5) == 0)
2584 /* If we don't need this section, strip it from the
2585 output file. This is mostly to handle .rela.bss and
2586 .rela.plt. We must create both sections in
2587 create_dynamic_sections, because they must be created
2588 before the linker maps input sections to output
2589 sections. The linker does that before
2590 adjust_dynamic_symbol is called, and it is that
2591 function which decides whether anything needs to go
2592 into these sections. */
2599 /* We use the reloc_count field as a counter if we need
2600 to copy relocs into the output file. */
2604 else if (strncmp (name
, ".got", 4) != 0)
2606 /* It's not one of our sections, so don't allocate space. */
2612 s
->flags
|= SEC_EXCLUDE
;
2616 /* Allocate memory for the section contents. */
2617 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
2618 Unused entries should be reclaimed before the section's contents
2619 are written out, but at the moment this does not happen. Thus in
2620 order to prevent writing out garbage, we initialise the section's
2621 contents to zero. */
2622 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
2623 if (s
->contents
== NULL
&& s
->size
!= 0)
2627 if (elf_hash_table (info
)->dynamic_sections_created
)
2629 /* Add some entries to the .dynamic section. We fill in the
2630 values later, in bfin_finish_dynamic_sections, but we
2631 must add the entries now so that we get the correct size for
2632 the .dynamic section. The DT_DEBUG entry is filled in by the
2633 dynamic linker and used by the debugger. */
2634 #define add_dynamic_entry(TAG, VAL) \
2635 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2639 if (!add_dynamic_entry (DT_DEBUG
, 0))
2646 if (!add_dynamic_entry (DT_RELA
, 0)
2647 || !add_dynamic_entry (DT_RELASZ
, 0)
2648 || !add_dynamic_entry (DT_RELAENT
,
2649 sizeof (Elf32_External_Rela
)))
2653 if ((info
->flags
& DF_TEXTREL
) != 0)
2655 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2659 #undef add_dynamic_entry
2664 /* Given a .data section and a .emreloc in-memory section, store
2665 relocation information into the .emreloc section which can be
2666 used at runtime to relocate the section. This is called by the
2667 linker when the --embedded-relocs switch is used. This is called
2668 after the add_symbols entry point has been called for all the
2669 objects, and before the final_link entry point is called. */
2672 bfd_bfin_elf32_create_embedded_relocs (
2674 struct bfd_link_info
*info
,
2679 Elf_Internal_Shdr
*symtab_hdr
;
2680 Elf_Internal_Sym
*isymbuf
= NULL
;
2681 Elf_Internal_Rela
*internal_relocs
= NULL
;
2682 Elf_Internal_Rela
*irel
, *irelend
;
2686 BFD_ASSERT (! info
->relocatable
);
2690 if (datasec
->reloc_count
== 0)
2693 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2695 /* Get a copy of the native relocations. */
2696 internal_relocs
= (_bfd_elf_link_read_relocs
2697 (abfd
, datasec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
2698 info
->keep_memory
));
2699 if (internal_relocs
== NULL
)
2702 amt
= (bfd_size_type
) datasec
->reloc_count
* 12;
2703 relsec
->contents
= (bfd_byte
*) bfd_alloc (abfd
, amt
);
2704 if (relsec
->contents
== NULL
)
2707 p
= relsec
->contents
;
2709 irelend
= internal_relocs
+ datasec
->reloc_count
;
2710 for (irel
= internal_relocs
; irel
< irelend
; irel
++, p
+= 12)
2712 asection
*targetsec
;
2714 /* We are going to write a four byte longword into the runtime
2715 reloc section. The longword will be the address in the data
2716 section which must be relocated. It is followed by the name
2717 of the target section NUL-padded or truncated to 8
2720 /* We can only relocate absolute longword relocs at run time. */
2721 if (ELF32_R_TYPE (irel
->r_info
) != (int) R_byte4_data
)
2723 *errmsg
= _("unsupported reloc type");
2724 bfd_set_error (bfd_error_bad_value
);
2728 /* Get the target section referred to by the reloc. */
2729 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
2731 /* A local symbol. */
2732 Elf_Internal_Sym
*isym
;
2734 /* Read this BFD's local symbols if we haven't done so already. */
2735 if (isymbuf
== NULL
)
2737 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
2738 if (isymbuf
== NULL
)
2739 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
2740 symtab_hdr
->sh_info
, 0,
2742 if (isymbuf
== NULL
)
2746 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
2747 targetsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2752 struct elf_link_hash_entry
*h
;
2754 /* An external symbol. */
2755 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
2756 h
= elf_sym_hashes (abfd
)[indx
];
2757 BFD_ASSERT (h
!= NULL
);
2758 if (h
->root
.type
== bfd_link_hash_defined
2759 || h
->root
.type
== bfd_link_hash_defweak
)
2760 targetsec
= h
->root
.u
.def
.section
;
2765 bfd_put_32 (abfd
, irel
->r_offset
+ datasec
->output_offset
, p
);
2766 memset (p
+ 4, 0, 8);
2767 if (targetsec
!= NULL
)
2768 strncpy ((char *) p
+ 4, targetsec
->output_section
->name
, 8);
2771 if (isymbuf
!= NULL
&& symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
2773 if (internal_relocs
!= NULL
2774 && elf_section_data (datasec
)->relocs
!= internal_relocs
)
2775 free (internal_relocs
);
2779 if (isymbuf
!= NULL
&& symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
2781 if (internal_relocs
!= NULL
2782 && elf_section_data (datasec
)->relocs
!= internal_relocs
)
2783 free (internal_relocs
);
2787 #define TARGET_LITTLE_SYM bfd_elf32_bfin_vec
2788 #define TARGET_LITTLE_NAME "elf32-bfin"
2789 #define ELF_ARCH bfd_arch_bfin
2790 #define ELF_MACHINE_CODE EM_BLACKFIN
2791 #define ELF_MAXPAGESIZE 0x1000
2792 #define elf_symbol_leading_char '_'
2794 #define bfd_elf32_bfd_reloc_type_lookup bfin_bfd_reloc_type_lookup
2795 #define elf_info_to_howto bfin_info_to_howto
2796 #define elf_info_to_howto_rel 0
2798 #define bfd_elf32_bfd_is_local_label_name \
2799 bfin_is_local_label_name
2800 #define bfin_hash_table(p) \
2801 ((struct bfin_link_hash_table *) (p)->hash)
2805 #define elf_backend_create_dynamic_sections \
2806 _bfd_elf_create_dynamic_sections
2807 #define bfd_elf32_bfd_link_hash_table_create \
2808 bfin_link_hash_table_create
2809 #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
2811 #define elf_backend_check_relocs bfin_check_relocs
2812 #define elf_backend_adjust_dynamic_symbol \
2813 bfin_adjust_dynamic_symbol
2814 #define elf_backend_size_dynamic_sections \
2815 bfin_size_dynamic_sections
2816 #define elf_backend_relocate_section bfin_relocate_section
2817 #define elf_backend_finish_dynamic_symbol \
2818 bfin_finish_dynamic_symbol
2819 #define elf_backend_finish_dynamic_sections \
2820 bfin_finish_dynamic_sections
2821 #define elf_backend_gc_mark_hook bfin_gc_mark_hook
2822 #define elf_backend_gc_sweep_hook bfin_gc_sweep_hook
2823 #define bfd_elf32_bfd_merge_private_bfd_data \
2824 elf32_bfin_merge_private_bfd_data
2825 #define bfd_elf32_bfd_set_private_flags \
2826 elf32_bfin_set_private_flags
2827 #define bfd_elf32_bfd_print_private_bfd_data \
2828 elf32_bfin_print_private_bfd_data
2829 #define elf_backend_reloc_type_class elf32_bfin_reloc_type_class
2830 #define elf_backend_can_gc_sections 1
2831 #define elf_backend_can_refcount 1
2832 #define elf_backend_want_got_plt 0
2833 #define elf_backend_plt_readonly 1
2834 #define elf_backend_want_plt_sym 0
2835 #define elf_backend_got_header_size 12
2836 #define elf_backend_rela_normal 1
2839 #include "elf32-target.h"