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,
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 if (symbol
->flags
& BSF_SECTION_SYM
)
438 /* Add in supplied addend. */
439 relocation
+= reloc_entry
->addend
;
444 relocation
= reloc_stack_pop ();
449 reloc_entry
->address
+= input_section
->output_offset
;
450 reloc_entry
->addend
+= symbol
->section
->output_offset
;
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
,
463 bfd_arch_bits_per_address(abfd
),
465 if (flag
!= bfd_reloc_ok
)
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
;
476 bfd_put_16 (abfd
, x
, (unsigned char *) data
+ reloc_addr
);
481 static bfd_reloc_status_type
482 bfin_byte4_reloc (bfd
*abfd
,
483 arelent
*reloc_entry
,
486 asection
*input_section
,
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
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. */
513 output_base
= output_section
->vma
;
516 && symbol
->section
->name
517 && !strcmp (symbol
->name
, symbol
->section
->name
))
520 relocation
+= output_base
+ symbol
->section
->output_offset
;
523 relocation
+= reloc_entry
->addend
;
527 relocation
= reloc_stack_pop();
528 relocation
+= reloc_entry
->addend
;
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
;
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;
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
);
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
,
560 asection
*input_section
,
562 char **error_message ATTRIBUTE_UNUSED
)
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
580 return bfd_reloc_undefined
;
582 /* Get symbol value. (Common symbols are special.) */
583 if (bfd_is_com_section (symbol
->section
))
586 relocation
= symbol
->value
;
588 output_section
= symbol
->section
->output_section
;
590 /* Convert input-section-relative symbol value to absolute. */
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
;
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
;
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
,
635 bfd_arch_bits_per_address(abfd
),
637 if (status
!= bfd_reloc_ok
)
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
;
655 x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
657 /* handle 8 and 16 bit relocations here. */
662 char x
= bfd_get_8 (abfd
, (char *) data
+ addr
);
664 bfd_put_8 (abfd
, x
, (unsigned char *) data
+ addr
);
670 unsigned short x
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ addr
);
672 bfd_put_16 (abfd
, (bfd_vma
) x
, (unsigned char *) data
+ addr
);
677 return bfd_reloc_other
;
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 *));
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. */
740 2, /* size (0 = byte, 1 = short, 2 = long). */
742 FALSE
, /* pc_relative. */
744 complain_overflow_bitfield
, /* complain_on_overflow. */
745 bfd_elf_generic_reloc
, /* special_function. */
746 "R_unused0", /* name. */
747 FALSE
, /* partial_inplace. */
750 FALSE
), /* pcrel_offset. */
752 HOWTO (R_pcrel5m2
, /* type. */
754 1, /* size (0 = byte, 1 = short, 2 = long).. */
756 TRUE
, /* pc_relative. */
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. */
768 2, /* size (0 = byte, 1 = short, 2 = long). */
770 FALSE
, /* pc_relative. */
772 complain_overflow_bitfield
, /* complain_on_overflow. */
773 bfd_elf_generic_reloc
, /* special_function. */
774 "R_unused1", /* name. */
775 FALSE
, /* partial_inplace. */
778 FALSE
), /* pcrel_offset. */
780 HOWTO (R_pcrel10
, /* type. */
782 1, /* size (0 = byte, 1 = short, 2 = long). */
784 TRUE
, /* pc_relative. */
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. */
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). */
802 TRUE
, /* pc_relative. */
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. */
814 1, /* size (0 = byte, 1 = short, 2 = long). */
816 FALSE
, /* pc_relative. */
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. */
828 1, /* size (0 = byte, 1 = short, 2 = long). */
830 FALSE
, /* pc_relative. */
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). */
844 FALSE
, /* pc_relative. */
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. */
856 1, /* size (0 = byte, 1 = short, 2 = long). */
858 TRUE
, /* pc_relative. */
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. */
870 2, /* size (0 = byte, 1 = short, 2 = long). */
872 TRUE
, /* pc_relative. */
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. */
884 2, /* size (0 = byte, 1 = short, 2 = long). */
886 TRUE
, /* pc_relative. */
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. */
898 2, /* size (0 = byte, 1 = short, 2 = long). */
900 FALSE
, /* pc_relative. */
902 complain_overflow_dont
, /* complain_on_overflow. */
903 bfd_elf_generic_reloc
, /* special_function. */
904 "R_unusedb", /* name. */
905 FALSE
, /* partial_inplace. */
908 FALSE
), /* pcrel_offset. */
910 HOWTO (R_unusedc
, /* type. */
912 2, /* size (0 = byte, 1 = short, 2 = long). */
914 FALSE
, /* pc_relative. */
916 complain_overflow_dont
, /* complain_on_overflow. */
917 bfd_elf_generic_reloc
, /* special_function. */
918 "R_unusedc", /* name. */
919 FALSE
, /* partial_inplace. */
922 FALSE
), /* pcrel_offset. */
924 HOWTO (R_pcrel24_jump_l
, /* type. */
926 2, /* size (0 = byte, 1 = short, 2 = long). */
928 TRUE
, /* pc_relative. */
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. */
940 2, /* size (0 = byte, 1 = short, 2 = long). */
942 TRUE
, /* pc_relative. */
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. */
954 2, /* size (0 = byte, 1 = short, 2 = long). */
956 FALSE
, /* pc_relative. */
958 complain_overflow_bitfield
, /* complain_on_overflow. */
959 bfin_bfd_reloc
, /* special_function. */
960 "R_var_eq_symb", /* name. */
961 FALSE
, /* partial_inplace. */
964 FALSE
), /* pcrel_offset. */
966 HOWTO (R_byte_data
, /* type. */
968 0, /* size (0 = byte, 1 = short, 2 = long). */
970 FALSE
, /* pc_relative. */
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. */
982 1, /* size (0 = byte, 1 = short, 2 = long). */
984 FALSE
, /* pc_relative. */
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. */
996 2, /* size (0 = byte, 1 = short, 2 = long). */
998 FALSE
, /* pc_relative. */
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). */
1012 TRUE
, /* pc_relative. */
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
[] =
1031 complain_overflow_dont
,
1045 complain_overflow_dont
,
1059 complain_overflow_dont
,
1073 complain_overflow_dont
,
1087 complain_overflow_dont
,
1095 HOWTO (R_div
, /* type. */
1096 0, /* rightshift. */
1097 0, /* size (0 = byte, 1 = short, 2 = long). */
1099 FALSE
, /* pc_relative. */
1101 complain_overflow_dont
, /* complain_on_overflow. */
1102 bfin_oper_reloc
, /* special_function. */
1103 "R_expst_div", /* name. */
1104 FALSE
, /* partial_inplace. */
1107 FALSE
), /* pcrel_offset. */
1109 HOWTO (R_mod
, /* type. */
1110 0, /* rightshift. */
1111 0, /* size (0 = byte, 1 = short, 2 = long). */
1113 FALSE
, /* pc_relative. */
1115 complain_overflow_dont
, /* complain_on_overflow. */
1116 bfin_oper_reloc
, /* special_function. */
1117 "R_expst_mod", /* name. */
1118 FALSE
, /* partial_inplace. */
1121 FALSE
), /* pcrel_offset. */
1123 HOWTO (R_lshift
, /* type. */
1124 0, /* rightshift. */
1125 0, /* size (0 = byte, 1 = short, 2 = long). */
1127 FALSE
, /* pc_relative. */
1129 complain_overflow_dont
, /* complain_on_overflow. */
1130 bfin_oper_reloc
, /* special_function. */
1131 "R_expst_lshift", /* name. */
1132 FALSE
, /* partial_inplace. */
1135 FALSE
), /* pcrel_offset. */
1137 HOWTO (R_rshift
, /* type. */
1138 0, /* rightshift. */
1139 0, /* size (0 = byte, 1 = short, 2 = long). */
1141 FALSE
, /* pc_relative. */
1143 complain_overflow_dont
, /* complain_on_overflow. */
1144 bfin_oper_reloc
, /* special_function. */
1145 "R_expst_rshift", /* name. */
1146 FALSE
, /* partial_inplace. */
1149 FALSE
), /* pcrel_offset. */
1151 HOWTO (R_and
, /* type. */
1152 0, /* rightshift. */
1153 0, /* size (0 = byte, 1 = short, 2 = long). */
1155 FALSE
, /* pc_relative. */
1157 complain_overflow_dont
, /* complain_on_overflow. */
1158 bfin_oper_reloc
, /* special_function. */
1159 "R_expst_and", /* name. */
1160 FALSE
, /* partial_inplace. */
1163 FALSE
), /* pcrel_offset. */
1165 HOWTO (R_or
, /* type. */
1166 0, /* rightshift. */
1167 0, /* size (0 = byte, 1 = short, 2 = long). */
1169 FALSE
, /* pc_relative. */
1171 complain_overflow_dont
, /* complain_on_overflow. */
1172 bfin_oper_reloc
, /* special_function. */
1173 "R_expst_or", /* name. */
1174 FALSE
, /* partial_inplace. */
1177 FALSE
), /* pcrel_offset. */
1179 HOWTO (R_xor
, /* type. */
1180 0, /* rightshift. */
1181 0, /* size (0 = byte, 1 = short, 2 = long). */
1183 FALSE
, /* pc_relative. */
1185 complain_overflow_dont
, /* complain_on_overflow. */
1186 bfin_oper_reloc
, /* special_function. */
1187 "R_expst_xor", /* name. */
1188 FALSE
, /* partial_inplace. */
1191 FALSE
), /* pcrel_offset. */
1193 HOWTO (R_land
, /* type. */
1194 0, /* rightshift. */
1195 0, /* size (0 = byte, 1 = short, 2 = long). */
1197 FALSE
, /* pc_relative. */
1199 complain_overflow_dont
, /* complain_on_overflow. */
1200 bfin_oper_reloc
, /* special_function. */
1201 "R_expst_land", /* name. */
1202 FALSE
, /* partial_inplace. */
1205 FALSE
), /* pcrel_offset. */
1207 HOWTO (R_lor
, /* type. */
1208 0, /* rightshift. */
1209 0, /* size (0 = byte, 1 = short, 2 = long). */
1211 FALSE
, /* pc_relative. */
1213 complain_overflow_dont
, /* complain_on_overflow. */
1214 bfin_oper_reloc
, /* special_function. */
1215 "R_expst_lor", /* name. */
1216 FALSE
, /* partial_inplace. */
1219 FALSE
), /* pcrel_offset. */
1221 HOWTO (R_len
, /* type. */
1222 0, /* rightshift. */
1223 0, /* size (0 = byte, 1 = short, 2 = long). */
1225 FALSE
, /* pc_relative. */
1227 complain_overflow_dont
, /* complain_on_overflow. */
1228 bfin_oper_reloc
, /* special_function. */
1229 "R_expst_len", /* name. */
1230 FALSE
, /* partial_inplace. */
1233 FALSE
), /* pcrel_offset. */
1235 HOWTO (R_neg
, /* type. */
1236 0, /* rightshift. */
1237 0, /* size (0 = byte, 1 = short, 2 = long). */
1239 FALSE
, /* pc_relative. */
1241 complain_overflow_dont
, /* complain_on_overflow. */
1242 bfin_oper_reloc
, /* special_function. */
1243 "R_expst_neg", /* name. */
1244 FALSE
, /* partial_inplace. */
1247 FALSE
), /* pcrel_offset. */
1249 HOWTO (R_comp
, /* type. */
1250 0, /* rightshift. */
1251 0, /* size (0 = byte, 1 = short, 2 = long). */
1253 FALSE
, /* pc_relative. */
1255 complain_overflow_dont
, /* complain_on_overflow. */
1256 bfin_oper_reloc
, /* special_function. */
1257 "R_expst_comp", /* name. */
1258 FALSE
, /* partial_inplace. */
1261 FALSE
), /* pcrel_offset. */
1263 HOWTO (R_page
, /* type. */
1264 0, /* rightshift. */
1265 0, /* size (0 = byte, 1 = short, 2 = long). */
1267 FALSE
, /* pc_relative. */
1269 complain_overflow_dont
, /* complain_on_overflow. */
1270 bfin_oper_reloc
, /* special_function. */
1271 "R_expst_page", /* name. */
1272 FALSE
, /* partial_inplace. */
1275 FALSE
), /* pcrel_offset. */
1277 HOWTO (R_hwpage
, /* type. */
1278 0, /* rightshift. */
1279 0, /* size (0 = byte, 1 = short, 2 = long). */
1281 FALSE
, /* pc_relative. */
1283 complain_overflow_dont
, /* complain_on_overflow. */
1284 bfin_oper_reloc
, /* special_function. */
1285 "R_expst_hwpage", /* name. */
1286 FALSE
, /* partial_inplace. */
1289 FALSE
), /* pcrel_offset. */
1291 HOWTO (R_addr
, /* type. */
1292 0, /* rightshift. */
1293 0, /* size (0 = byte, 1 = short, 2 = long). */
1295 FALSE
, /* pc_relative. */
1297 complain_overflow_dont
, /* complain_on_overflow. */
1298 bfin_oper_reloc
, /* special_function. */
1299 "R_expst_addr", /* name. */
1300 FALSE
, /* partial_inplace. */
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). */
1312 FALSE
, /* pc_relative. */
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). */
1326 FALSE
, /* pc_relative. */
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). */
1341 FALSE
, /* pc_relative. */
1343 complain_overflow_dont
, /* complain_on_overflow. */
1344 NULL
, /* special_function. */
1345 "R_BFIN_GNU_VTINHERIT", /* name. */
1346 FALSE
, /* partial_inplace. */
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). */
1356 FALSE
, /* pc_relative. */
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. */
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
}
1423 bfin_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
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
];
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
)
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$. */
1489 bfin_is_local_label_name (
1490 bfd
*abfd ATTRIBUTE_UNUSED
,
1493 if (label
[0] == 'L' && label
[1] == '$' )
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
1505 bfin_check_relocs (bfd
* abfd
,
1506 struct bfd_link_info
*info
,
1508 const Elf_Internal_Rela
*relocs
)
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
;
1519 if (info
->relocatable
)
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
);
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
)
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
))
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
))
1561 && strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
1567 /* Create the .got section. */
1568 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
1569 if (!_bfd_elf_create_got_section (dynobj
, info
))
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");
1586 || !bfd_set_section_flags (dynobj
, srelgot
,
1591 | SEC_LINKER_CREATED
1593 || !bfd_set_section_alignment (dynobj
, srelgot
, 2))
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
))
1609 /* Allocate space in the .got section. */
1611 /* Allocate relocation space. */
1612 srelgot
->size
+= sizeof (Elf32_External_Rela
);
1618 /* This is a global offset table entry for a local symbol. */
1619 if (local_got_refcounts
== NULL
)
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
)
1629 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
1631 if (local_got_refcounts
[r_symndx
] == 0)
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
]++;
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
))
1660 return reloc_class_normal
;
1664 bfin_relocate_section (bfd
* output_bfd
,
1665 struct bfd_link_info
*info
,
1667 asection
* input_section
,
1668 bfd_byte
* contents
,
1669 Elf_Internal_Rela
* relocs
,
1670 Elf_Internal_Sym
* local_syms
,
1671 asection
** local_sections
)
1674 Elf_Internal_Shdr
*symtab_hdr
;
1675 struct elf_link_hash_entry
**sym_hashes
;
1676 bfd_vma
*local_got_offsets
;
1679 Elf_Internal_Rela
*rel
;
1680 Elf_Internal_Rela
*relend
;
1681 char *error_msg
= NULL
;
1684 if (info
->relocatable
)
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
);
1696 relend
= relocs
+ input_section
->reloc_count
;
1697 for (; rel
< relend
; rel
++, i
++)
1700 reloc_howto_type
*howto
;
1701 unsigned long r_symndx
;
1702 struct elf_link_hash_entry
*h
;
1703 Elf_Internal_Sym
*sym
;
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
);
1716 if (r_type
== R_BFIN_GNU_VTENTRY
1717 || r_type
== R_BFIN_GNU_VTINHERIT
)
1720 howto
= bfin_reloc_type_lookup (input_bfd
, r_type
);
1723 bfd_set_error (bfd_error_bad_value
);
1726 r_symndx
= ELF32_R_SYM (rel
->r_info
);
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
];
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
;
1752 (!strcmp (h
->root
.root
.string
, ".__constant")
1753 || !strcmp (h
->root
.root
.string
, ".__operator")))
1757 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1758 r_symndx
, symtab_hdr
, sym_hashes
,
1760 unresolved_reloc
, warned
);
1767 case R_BFIN_GNU_VTINHERIT
:
1768 case R_BFIN_GNU_VTENTRY
:
1769 return bfd_reloc_ok
;
1772 /* Relocation is to the address of the entry for this symbol
1773 in the global offset table. */
1775 && strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
1778 /* Relocation is the offset of the entry for this symbol in
1779 the global offset table. */
1786 sgot
= bfd_get_section_by_name (dynobj
, ".got");
1787 BFD_ASSERT (sgot
!= NULL
);
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
)
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. */
1820 bfd_put_32 (output_bfd
, relocation
,
1821 sgot
->contents
+ off
);
1826 unresolved_reloc
= FALSE
;
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. */
1843 bfd_put_32 (output_bfd
, relocation
, sgot
->contents
+ off
);
1848 Elf_Internal_Rela outrel
;
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
);
1857 ELF32_R_INFO (0, R_pcrel24
);
1858 outrel
.r_addend
= relocation
;
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
;
1871 /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
1877 if (howto
->special_function
)
1879 bfd_reloc_status_type cont
;
1884 symbol
.section
= bfd_und_section_ptr
;
1889 if (unresolved_reloc
)
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
;
1910 symbol
= *sec
->symbol
;
1912 reloc_ent
.address
= rel
->r_offset
;
1913 reloc_ent
.howto
= howto
;
1914 reloc_ent
.addend
= rel
->r_addend
;
1916 reloc_ent
.sym_ptr_ptr
= &symbol1
;
1919 howto
->special_function (input_bfd
, &reloc_ent
, &symbol
,
1920 contents
, input_section
,
1922 relocatable
? output_bfd
: NULL
,
1924 if (cont
== bfd_reloc_ok
)
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
);
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'"),
1948 input_section
, (long) rel
->r_offset
, h
->root
.root
.string
);
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
)
1961 name
= h
->root
.root
.string
;
1964 name
= bfd_elf_string_from_elf_section (input_bfd
,
1965 symtab_hdr
->sh_link
,
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
)))
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
);
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
)
2003 switch (ELF32_R_TYPE (rel
->r_info
))
2006 case R_BFIN_GNU_VTINHERIT
:
2007 case R_BFIN_GNU_VTENTRY
:
2011 switch (h
->root
.type
)
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
;
2026 return bfd_section_from_elf_index (sec
->owner
, sym
->st_shndx
);
2032 /* Update the got entry reference counts for the section being removed. */
2035 bfin_gc_sweep_hook (bfd
* abfd
,
2036 struct bfd_link_info
*info
,
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
;
2048 dynobj
= elf_hash_table (info
)->dynobj
;
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
))
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)
2075 if (h
->got
.refcount
== 0)
2077 /* We don't need the .got entry any more. */
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. */
2093 srelgot
->size
-= sizeof (Elf32_External_Rela
);
2107 /* Merge backend specific data from an object file to the output
2108 object file when linking. */
2110 elf32_bfin_merge_private_bfd_data (bfd
* ibfd
, bfd
* obfd
)
2115 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
2116 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
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
;
2133 elf32_bfin_set_private_flags (bfd
* abfd
, flagword flags
)
2135 elf_elfheader (abfd
)->e_flags
= flags
;
2136 elf_flags_init (abfd
) = TRUE
;
2141 /* Display the flags field. */
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
);
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
2194 ret
= bfd_hash_allocate (table
, sizeof (struct bfin_link_hash_entry
));
2198 /* Call the allocation method of the superclass. */
2199 ret
= _bfd_elf_link_hash_newfunc (ret
, table
, string
);
2201 bfin_hash_entry (ret
)->pcrel_relocs_copied
= NULL
;
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
)
2218 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
,
2219 bfin_link_hash_newfunc
))
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. */
2235 bfin_finish_dynamic_sections (bfd
* output_bfd ATTRIBUTE_UNUSED
,
2236 struct bfd_link_info
*info
)
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
);
2265 /* Finish up dynamic symbol handling. We set the contents of various
2266 dynamic sections here. */
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
)
2276 dynobj
= elf_hash_table (info
)->dynobj
;
2278 if (h
->got
.offset
!= (bfd_vma
) - 1)
2282 Elf_Internal_Rela rela
;
2285 /* This symbol has an entry in the global offset table.
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. */
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
,
2311 offset
& ~(bfd_vma
) 1)));
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
);
2321 loc
= srela
->contents
;
2322 loc
+= srela
->reloc_count
++ * sizeof (Elf32_External_Rela
);
2323 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
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
;
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
2345 bfin_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2346 struct elf_link_hash_entry
*h
)
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
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
)
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
;
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. */
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)
2411 srel
= bfd_get_section_by_name (dynobj
, ".rela.bss");
2412 BFD_ASSERT (srel
!= NULL
);
2413 srel
->size
+= sizeof (Elf32_External_Rela
);
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)
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
))
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. */
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
2453 struct bfin_pcrel_relocs_copied
*next
;
2454 /* A section in dynobj. */
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
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
;
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
);
2506 /* Set the sizes of the dynamic sections. */
2507 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
2510 bfin_size_dynamic_sections (bfd
* output_bfd ATTRIBUTE_UNUSED
,
2511 struct bfd_link_info
*info
)
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
;
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
2538 s
= bfd_get_section_by_name (dynobj
, ".rela.got");
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. */
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
2557 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
2562 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
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
);
2571 if (strncmp (name
, ".rela", 5) == 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. */
2590 /* We use the reloc_count field as a counter if we need
2591 to copy relocs into the output file. */
2595 else if (strncmp (name
, ".got", 4) != 0)
2597 /* It's not one of our sections, so don't allocate space. */
2603 s
->flags
|= SEC_EXCLUDE
;
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)
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)
2630 if (!add_dynamic_entry (DT_DEBUG
, 0))
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
)))
2644 if ((info
->flags
& DF_TEXTREL
) != 0)
2646 if (!add_dynamic_entry (DT_TEXTREL
, 0))
2650 #undef add_dynamic_entry
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. */
2663 bfd_bfin_elf32_create_embedded_relocs (
2665 struct bfd_link_info
*info
,
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
;
2677 BFD_ASSERT (! info
->relocatable
);
2681 if (datasec
->reloc_count
== 0)
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
)
2693 amt
= (bfd_size_type
) datasec
->reloc_count
* 12;
2694 relsec
->contents
= (bfd_byte
*) bfd_alloc (abfd
, amt
);
2695 if (relsec
->contents
== NULL
)
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
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
);
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,
2733 if (isymbuf
== NULL
)
2737 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
2738 targetsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
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
;
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
)
2764 if (internal_relocs
!= NULL
2765 && elf_section_data (datasec
)->relocs
!= internal_relocs
)
2766 free (internal_relocs
);
2770 if (isymbuf
!= NULL
&& symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
2772 if (internal_relocs
!= NULL
2773 && elf_section_data (datasec
)->relocs
!= internal_relocs
)
2774 free (internal_relocs
);
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"