1 /* 32-bit ELF support for TI C6X
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
25 #include "libiberty.h"
27 #include "elf/tic6x.h"
28 #include "elf32-tic6x.h"
30 struct elf32_tic6x_obj_tdata
32 struct elf_obj_tdata root;
34 /* Whether to use RELA relocations when generating relocations.
35 This is a per-object flag to allow the assembler to generate REL
36 relocations for use in linker testcases. */
37 bfd_boolean use_rela_p;
40 #define elf32_tic6x_tdata(abfd) \
41 ((struct elf32_tic6x_obj_tdata *) (abfd)->tdata.any)
43 static reloc_howto_type elf32_tic6x_howto_table[] =
45 HOWTO (R_C6000_NONE, /* type */
47 0, /* size (0 = byte, 1 = short, 2 = long) */
49 FALSE, /* pc_relative */
51 complain_overflow_dont,/* complain_on_overflow */
52 bfd_elf_generic_reloc, /* special_function */
53 "R_C6000_NONE", /* name */
54 FALSE, /* partial_inplace */
57 FALSE), /* pcrel_offset */
58 HOWTO (R_C6000_ABS32, /* type */
60 2, /* size (0 = byte, 1 = short, 2 = long) */
62 FALSE, /* pc_relative */
64 complain_overflow_dont,/* complain_on_overflow */
65 bfd_elf_generic_reloc, /* special_function */
66 "R_C6000_ABS32", /* name */
67 FALSE, /* partial_inplace */
69 0xffffffff, /* dst_mask */
70 FALSE), /* pcrel_offset */
71 HOWTO (R_C6000_ABS16, /* type */
73 1, /* size (0 = byte, 1 = short, 2 = long) */
75 FALSE, /* pc_relative */
77 complain_overflow_bitfield,/* complain_on_overflow */
78 bfd_elf_generic_reloc, /* special_function */
79 "R_C6000_ABS16", /* name */
80 FALSE, /* partial_inplace */
82 0x0000ffff, /* dst_mask */
83 FALSE), /* pcrel_offset */
84 HOWTO (R_C6000_ABS8, /* type */
86 0, /* size (0 = byte, 1 = short, 2 = long) */
88 FALSE, /* pc_relative */
90 complain_overflow_bitfield,/* complain_on_overflow */
91 bfd_elf_generic_reloc, /* special_function */
92 "R_C6000_ABS8", /* name */
93 FALSE, /* partial_inplace */
95 0x000000ff, /* dst_mask */
96 FALSE), /* pcrel_offset */
97 HOWTO (R_C6000_PCR_S21, /* type */
99 2, /* size (0 = byte, 1 = short, 2 = long) */
101 TRUE, /* pc_relative */
103 complain_overflow_signed,/* complain_on_overflow */
104 bfd_elf_generic_reloc, /* special_function */
105 "R_C6000_PCR_S21", /* name */
106 FALSE, /* partial_inplace */
108 0x0fffff80, /* dst_mask */
109 TRUE), /* pcrel_offset */
110 HOWTO (R_C6000_PCR_S12, /* type */
112 2, /* size (0 = byte, 1 = short, 2 = long) */
114 TRUE, /* pc_relative */
116 complain_overflow_signed,/* complain_on_overflow */
117 bfd_elf_generic_reloc, /* special_function */
118 "R_C6000_PCR_S12", /* name */
119 FALSE, /* partial_inplace */
121 0x0fff0000, /* dst_mask */
122 TRUE), /* pcrel_offset */
123 HOWTO (R_C6000_PCR_S10, /* type */
125 2, /* size (0 = byte, 1 = short, 2 = long) */
127 TRUE, /* pc_relative */
129 complain_overflow_signed,/* complain_on_overflow */
130 bfd_elf_generic_reloc, /* special_function */
131 "R_C6000_PCR_S10", /* name */
132 FALSE, /* partial_inplace */
134 0x007fe000, /* dst_mask */
135 TRUE), /* pcrel_offset */
136 HOWTO (R_C6000_PCR_S7, /* type */
138 2, /* size (0 = byte, 1 = short, 2 = long) */
140 TRUE, /* pc_relative */
142 complain_overflow_signed,/* complain_on_overflow */
143 bfd_elf_generic_reloc, /* special_function */
144 "R_C6000_PCR_S7", /* name */
145 FALSE, /* partial_inplace */
147 0x007f0000, /* dst_mask */
148 TRUE), /* pcrel_offset */
149 HOWTO (R_C6000_ABS_S16, /* type */
151 2, /* size (0 = byte, 1 = short, 2 = long) */
153 FALSE, /* pc_relative */
155 complain_overflow_signed,/* complain_on_overflow */
156 bfd_elf_generic_reloc, /* special_function */
157 "R_C6000_ABS_S16", /* name */
158 FALSE, /* partial_inplace */
160 0x007fff80, /* dst_mask */
161 FALSE), /* pcrel_offset */
162 HOWTO (R_C6000_ABS_L16, /* type */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
166 FALSE, /* pc_relative */
168 complain_overflow_dont,/* complain_on_overflow */
169 bfd_elf_generic_reloc, /* special_function */
170 "R_C6000_ABS_L16", /* name */
171 FALSE, /* partial_inplace */
173 0x007fff80, /* dst_mask */
174 FALSE), /* pcrel_offset */
175 HOWTO (R_C6000_ABS_H16, /* type */
177 2, /* size (0 = byte, 1 = short, 2 = long) */
179 FALSE, /* pc_relative */
181 complain_overflow_dont,/* complain_on_overflow */
182 bfd_elf_generic_reloc, /* special_function */
183 "R_C6000_ABS_H16", /* name */
184 FALSE, /* partial_inplace */
186 0x007fff80, /* dst_mask */
187 FALSE), /* pcrel_offset */
188 HOWTO (R_C6000_SBR_U15_B, /* type */
190 2, /* size (0 = byte, 1 = short, 2 = long) */
192 FALSE, /* pc_relative */
194 complain_overflow_unsigned,/* complain_on_overflow */
195 bfd_elf_generic_reloc, /* special_function */
196 "R_C6000_SBR_U15_B", /* name */
197 FALSE, /* partial_inplace */
199 0x007fff00, /* dst_mask */
200 FALSE), /* pcrel_offset */
201 HOWTO (R_C6000_SBR_U15_H, /* type */
203 2, /* size (0 = byte, 1 = short, 2 = long) */
205 FALSE, /* pc_relative */
207 complain_overflow_unsigned,/* complain_on_overflow */
208 bfd_elf_generic_reloc, /* special_function */
209 "R_C6000_SBR_U15_H", /* name */
210 FALSE, /* partial_inplace */
212 0x007fff00, /* dst_mask */
213 FALSE), /* pcrel_offset */
214 HOWTO (R_C6000_SBR_U15_W, /* type */
216 2, /* size (0 = byte, 1 = short, 2 = long) */
218 FALSE, /* pc_relative */
220 complain_overflow_unsigned,/* complain_on_overflow */
221 bfd_elf_generic_reloc, /* special_function */
222 "R_C6000_SBR_U15_W", /* name */
223 FALSE, /* partial_inplace */
225 0x007fff00, /* dst_mask */
226 FALSE), /* pcrel_offset */
227 HOWTO (R_C6000_SBR_S16, /* type */
229 2, /* size (0 = byte, 1 = short, 2 = long) */
231 FALSE, /* pc_relative */
233 complain_overflow_signed,/* complain_on_overflow */
234 bfd_elf_generic_reloc, /* special_function */
235 "R_C6000_SBR_S16", /* name */
236 FALSE, /* partial_inplace */
238 0x007fff80, /* dst_mask */
239 FALSE), /* pcrel_offset */
240 HOWTO (R_C6000_SBR_L16_B, /* type */
242 2, /* size (0 = byte, 1 = short, 2 = long) */
244 FALSE, /* pc_relative */
246 complain_overflow_dont,/* complain_on_overflow */
247 bfd_elf_generic_reloc, /* special_function */
248 "R_C6000_SBR_L16_B", /* name */
249 FALSE, /* partial_inplace */
251 0x007fff80, /* dst_mask */
252 FALSE), /* pcrel_offset */
253 HOWTO (R_C6000_SBR_L16_H, /* type */
255 2, /* size (0 = byte, 1 = short, 2 = long) */
257 FALSE, /* pc_relative */
259 complain_overflow_dont,/* complain_on_overflow */
260 bfd_elf_generic_reloc, /* special_function */
261 "R_C6000_SBR_L16_H", /* name */
262 FALSE, /* partial_inplace */
264 0x007fff80, /* dst_mask */
265 FALSE), /* pcrel_offset */
266 HOWTO (R_C6000_SBR_L16_W, /* type */
268 2, /* size (0 = byte, 1 = short, 2 = long) */
270 FALSE, /* pc_relative */
272 complain_overflow_dont,/* complain_on_overflow */
273 bfd_elf_generic_reloc, /* special_function */
274 "R_C6000_SBR_L16_W", /* name */
275 FALSE, /* partial_inplace */
277 0x007fff80, /* dst_mask */
278 FALSE), /* pcrel_offset */
279 HOWTO (R_C6000_SBR_H16_B, /* type */
281 2, /* size (0 = byte, 1 = short, 2 = long) */
283 FALSE, /* pc_relative */
285 complain_overflow_dont,/* complain_on_overflow */
286 bfd_elf_generic_reloc, /* special_function */
287 "R_C6000_SBR_H16_B", /* name */
288 FALSE, /* partial_inplace */
290 0x007fff80, /* dst_mask */
291 FALSE), /* pcrel_offset */
292 HOWTO (R_C6000_SBR_H16_H, /* type */
294 2, /* size (0 = byte, 1 = short, 2 = long) */
296 FALSE, /* pc_relative */
298 complain_overflow_dont,/* complain_on_overflow */
299 bfd_elf_generic_reloc, /* special_function */
300 "R_C6000_SBR_H16_H", /* name */
301 FALSE, /* partial_inplace */
303 0x007fff80, /* dst_mask */
304 FALSE), /* pcrel_offset */
305 HOWTO (R_C6000_SBR_H16_W, /* type */
307 2, /* size (0 = byte, 1 = short, 2 = long) */
309 FALSE, /* pc_relative */
311 complain_overflow_dont,/* complain_on_overflow */
312 bfd_elf_generic_reloc, /* special_function */
313 "R_C6000_SBR_H16_W", /* name */
314 FALSE, /* partial_inplace */
316 0x007fff80, /* dst_mask */
317 FALSE), /* pcrel_offset */
318 HOWTO (R_C6000_SBR_GOT_U15_W, /* type */
320 2, /* size (0 = byte, 1 = short, 2 = long) */
322 FALSE, /* pc_relative */
324 complain_overflow_unsigned,/* complain_on_overflow */
325 bfd_elf_generic_reloc, /* special_function */
326 "R_C6000_SBR_GOT_U15_W",/* name */
327 FALSE, /* partial_inplace */
329 0x007fff00, /* dst_mask */
330 FALSE), /* pcrel_offset */
331 HOWTO (R_C6000_SBR_GOT_L16_W, /* type */
333 2, /* size (0 = byte, 1 = short, 2 = long) */
335 FALSE, /* pc_relative */
337 complain_overflow_dont,/* complain_on_overflow */
338 bfd_elf_generic_reloc, /* special_function */
339 "R_C6000_SBR_GOT_L16_W",/* name */
340 FALSE, /* partial_inplace */
342 0x007fff80, /* dst_mask */
343 FALSE), /* pcrel_offset */
344 HOWTO (R_C6000_SBR_GOT_H16_W, /* type */
346 2, /* size (0 = byte, 1 = short, 2 = long) */
348 FALSE, /* pc_relative */
350 complain_overflow_dont,/* complain_on_overflow */
351 bfd_elf_generic_reloc, /* special_function */
352 "R_C6000_SBR_GOT_H16_W",/* name */
353 FALSE, /* partial_inplace */
355 0x007fff80, /* dst_mask */
356 FALSE), /* pcrel_offset */
357 HOWTO (R_C6000_DSBT_INDEX, /* type */
359 2, /* size (0 = byte, 1 = short, 2 = long) */
361 FALSE, /* pc_relative */
363 complain_overflow_unsigned,/* complain_on_overflow */
364 bfd_elf_generic_reloc, /* special_function */
365 "R_C6000_DSBT_INDEX", /* name */
366 FALSE, /* partial_inplace */
368 0x007fff00, /* dst_mask */
369 FALSE), /* pcrel_offset */
370 HOWTO (R_C6000_PREL31, /* type */
372 2, /* size (0 = byte, 1 = short, 2 = long) */
374 FALSE, /* pc_relative */
376 complain_overflow_dont,/* complain_on_overflow */
377 bfd_elf_generic_reloc, /* special_function */
378 "R_C6000_PREL31", /* name */
379 FALSE, /* partial_inplace */
381 0x7fffffff, /* dst_mask */
382 FALSE), /* pcrel_offset */
383 HOWTO (R_C6000_COPY, /* type */
385 2, /* size (0 = byte, 1 = short, 2 = long) */
387 FALSE, /* pc_relative */
389 complain_overflow_dont,/* complain_on_overflow */
390 bfd_elf_generic_reloc, /* special_function */
391 "R_C6000_COPY", /* name */
392 FALSE, /* partial_inplace */
394 0xffffffff, /* dst_mask */
395 FALSE), /* pcrel_offset */
622 HOWTO (R_C6000_ALIGN, /* type */
624 0, /* size (0 = byte, 1 = short, 2 = long) */
626 FALSE, /* pc_relative */
628 complain_overflow_dont,/* complain_on_overflow */
629 bfd_elf_generic_reloc, /* special_function */
630 "R_C6000_ALIGN", /* name */
631 FALSE, /* partial_inplace */
634 FALSE), /* pcrel_offset */
635 HOWTO (R_C6000_FPHEAD, /* type */
637 0, /* size (0 = byte, 1 = short, 2 = long) */
639 FALSE, /* pc_relative */
641 complain_overflow_dont,/* complain_on_overflow */
642 bfd_elf_generic_reloc, /* special_function */
643 "R_C6000_FPHEAD", /* name */
644 FALSE, /* partial_inplace */
647 FALSE), /* pcrel_offset */
648 HOWTO (R_C6000_NOCMP, /* type */
650 0, /* size (0 = byte, 1 = short, 2 = long) */
652 FALSE, /* pc_relative */
654 complain_overflow_dont,/* complain_on_overflow */
655 bfd_elf_generic_reloc, /* special_function */
656 "R_C6000_NOCMP", /* name */
657 FALSE, /* partial_inplace */
660 FALSE) /* pcrel_offset */
663 static reloc_howto_type elf32_tic6x_howto_table_rel[] =
665 HOWTO (R_C6000_NONE, /* type */
667 0, /* size (0 = byte, 1 = short, 2 = long) */
669 FALSE, /* pc_relative */
671 complain_overflow_dont,/* complain_on_overflow */
672 bfd_elf_generic_reloc, /* special_function */
673 "R_C6000_NONE", /* name */
674 TRUE, /* partial_inplace */
677 FALSE), /* pcrel_offset */
678 HOWTO (R_C6000_ABS32, /* type */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
682 FALSE, /* pc_relative */
684 complain_overflow_dont,/* complain_on_overflow */
685 bfd_elf_generic_reloc, /* special_function */
686 "R_C6000_ABS32", /* name */
687 TRUE, /* partial_inplace */
688 0xffffffff, /* src_mask */
689 0xffffffff, /* dst_mask */
690 FALSE), /* pcrel_offset */
691 HOWTO (R_C6000_ABS16, /* type */
693 1, /* size (0 = byte, 1 = short, 2 = long) */
695 FALSE, /* pc_relative */
697 complain_overflow_bitfield,/* complain_on_overflow */
698 bfd_elf_generic_reloc, /* special_function */
699 "R_C6000_ABS16", /* name */
700 TRUE, /* partial_inplace */
701 0x0000ffff, /* src_mask */
702 0x0000ffff, /* dst_mask */
703 FALSE), /* pcrel_offset */
704 HOWTO (R_C6000_ABS8, /* type */
706 0, /* size (0 = byte, 1 = short, 2 = long) */
708 FALSE, /* pc_relative */
710 complain_overflow_bitfield,/* complain_on_overflow */
711 bfd_elf_generic_reloc, /* special_function */
712 "R_C6000_ABS8", /* name */
713 TRUE, /* partial_inplace */
714 0x000000ff, /* src_mask */
715 0x000000ff, /* dst_mask */
716 FALSE), /* pcrel_offset */
717 HOWTO (R_C6000_PCR_S21, /* type */
719 2, /* size (0 = byte, 1 = short, 2 = long) */
721 TRUE, /* pc_relative */
723 complain_overflow_signed,/* complain_on_overflow */
724 bfd_elf_generic_reloc, /* special_function */
725 "R_C6000_PCR_S21", /* name */
726 TRUE, /* partial_inplace */
727 0x0fffff80, /* src_mask */
728 0x0fffff80, /* dst_mask */
729 TRUE), /* pcrel_offset */
730 HOWTO (R_C6000_PCR_S12, /* type */
732 2, /* size (0 = byte, 1 = short, 2 = long) */
734 TRUE, /* pc_relative */
736 complain_overflow_signed,/* complain_on_overflow */
737 bfd_elf_generic_reloc, /* special_function */
738 "R_C6000_PCR_S12", /* name */
739 TRUE, /* partial_inplace */
740 0x0fff0000, /* src_mask */
741 0x0fff0000, /* dst_mask */
742 TRUE), /* pcrel_offset */
743 HOWTO (R_C6000_PCR_S10, /* type */
745 2, /* size (0 = byte, 1 = short, 2 = long) */
747 TRUE, /* pc_relative */
749 complain_overflow_signed,/* complain_on_overflow */
750 bfd_elf_generic_reloc, /* special_function */
751 "R_C6000_PCR_S10", /* name */
752 TRUE, /* partial_inplace */
753 0x007fe000, /* src_mask */
754 0x007fe000, /* dst_mask */
755 TRUE), /* pcrel_offset */
756 HOWTO (R_C6000_PCR_S7, /* type */
758 2, /* size (0 = byte, 1 = short, 2 = long) */
760 TRUE, /* pc_relative */
762 complain_overflow_signed,/* complain_on_overflow */
763 bfd_elf_generic_reloc, /* special_function */
764 "R_C6000_PCR_S7", /* name */
765 TRUE, /* partial_inplace */
766 0x007f0000, /* src_mask */
767 0x007f0000, /* dst_mask */
768 TRUE), /* pcrel_offset */
769 HOWTO (R_C6000_ABS_S16, /* type */
771 2, /* size (0 = byte, 1 = short, 2 = long) */
773 FALSE, /* pc_relative */
775 complain_overflow_signed,/* complain_on_overflow */
776 bfd_elf_generic_reloc, /* special_function */
777 "R_C6000_ABS_S16", /* name */
778 TRUE, /* partial_inplace */
779 0x007fff80, /* src_mask */
780 0x007fff80, /* dst_mask */
781 FALSE), /* pcrel_offset */
782 HOWTO (R_C6000_ABS_L16, /* type */
784 2, /* size (0 = byte, 1 = short, 2 = long) */
786 FALSE, /* pc_relative */
788 complain_overflow_dont,/* complain_on_overflow */
789 bfd_elf_generic_reloc, /* special_function */
790 "R_C6000_ABS_L16", /* name */
791 TRUE, /* partial_inplace */
792 0x007fff80, /* src_mask */
793 0x007fff80, /* dst_mask */
794 FALSE), /* pcrel_offset */
795 EMPTY_HOWTO (R_C6000_ABS_H16),
796 HOWTO (R_C6000_SBR_U15_B, /* type */
798 2, /* size (0 = byte, 1 = short, 2 = long) */
800 FALSE, /* pc_relative */
802 complain_overflow_unsigned,/* complain_on_overflow */
803 bfd_elf_generic_reloc, /* special_function */
804 "R_C6000_SBR_U15_B", /* name */
805 TRUE, /* partial_inplace */
806 0x007fff00, /* src_mask */
807 0x007fff00, /* dst_mask */
808 FALSE), /* pcrel_offset */
809 HOWTO (R_C6000_SBR_U15_H, /* type */
811 2, /* size (0 = byte, 1 = short, 2 = long) */
813 FALSE, /* pc_relative */
815 complain_overflow_unsigned,/* complain_on_overflow */
816 bfd_elf_generic_reloc, /* special_function */
817 "R_C6000_SBR_U15_H", /* name */
818 TRUE, /* partial_inplace */
819 0x007fff00, /* src_mask */
820 0x007fff00, /* dst_mask */
821 FALSE), /* pcrel_offset */
822 HOWTO (R_C6000_SBR_U15_W, /* type */
824 2, /* size (0 = byte, 1 = short, 2 = long) */
826 FALSE, /* pc_relative */
828 complain_overflow_unsigned,/* complain_on_overflow */
829 bfd_elf_generic_reloc, /* special_function */
830 "R_C6000_SBR_U15_W", /* name */
831 TRUE, /* partial_inplace */
832 0x007fff00, /* src_mask */
833 0x007fff00, /* dst_mask */
834 FALSE), /* pcrel_offset */
835 HOWTO (R_C6000_SBR_S16, /* type */
837 2, /* size (0 = byte, 1 = short, 2 = long) */
839 FALSE, /* pc_relative */
841 complain_overflow_signed,/* complain_on_overflow */
842 bfd_elf_generic_reloc, /* special_function */
843 "R_C6000_SBR_S16", /* name */
844 TRUE, /* partial_inplace */
845 0x007fff80, /* src_mask */
846 0x007fff80, /* dst_mask */
847 FALSE), /* pcrel_offset */
848 HOWTO (R_C6000_SBR_L16_B, /* type */
850 2, /* size (0 = byte, 1 = short, 2 = long) */
852 FALSE, /* pc_relative */
854 complain_overflow_dont,/* complain_on_overflow */
855 bfd_elf_generic_reloc, /* special_function */
856 "R_C6000_SBR_L16_B", /* name */
857 TRUE, /* partial_inplace */
858 0x007fff80, /* src_mask */
859 0x007fff80, /* dst_mask */
860 FALSE), /* pcrel_offset */
861 HOWTO (R_C6000_SBR_L16_H, /* type */
863 2, /* size (0 = byte, 1 = short, 2 = long) */
865 FALSE, /* pc_relative */
867 complain_overflow_dont,/* complain_on_overflow */
868 bfd_elf_generic_reloc, /* special_function */
869 "R_C6000_SBR_L16_H", /* name */
870 TRUE, /* partial_inplace */
871 0x007fff80, /* src_mask */
872 0x007fff80, /* dst_mask */
873 FALSE), /* pcrel_offset */
874 HOWTO (R_C6000_SBR_L16_W, /* type */
876 2, /* size (0 = byte, 1 = short, 2 = long) */
878 FALSE, /* pc_relative */
880 complain_overflow_dont,/* complain_on_overflow */
881 bfd_elf_generic_reloc, /* special_function */
882 "R_C6000_SBR_L16_W", /* name */
883 TRUE, /* partial_inplace */
884 0x007fff80, /* src_mask */
885 0x007fff80, /* dst_mask */
886 FALSE), /* pcrel_offset */
887 EMPTY_HOWTO (R_C6000_SBR_H16_B),
888 EMPTY_HOWTO (R_C6000_SBR_H16_H),
889 EMPTY_HOWTO (R_C6000_SBR_H16_W),
890 HOWTO (R_C6000_SBR_GOT_U15_W, /* type */
892 2, /* size (0 = byte, 1 = short, 2 = long) */
894 FALSE, /* pc_relative */
896 complain_overflow_unsigned,/* complain_on_overflow */
897 bfd_elf_generic_reloc, /* special_function */
898 "R_C6000_SBR_GOT_U15_W",/* name */
899 TRUE, /* partial_inplace */
900 0x007fff00, /* src_mask */
901 0x007fff00, /* dst_mask */
902 FALSE), /* pcrel_offset */
903 HOWTO (R_C6000_SBR_GOT_L16_W, /* type */
905 2, /* size (0 = byte, 1 = short, 2 = long) */
907 FALSE, /* pc_relative */
909 complain_overflow_dont,/* complain_on_overflow */
910 bfd_elf_generic_reloc, /* special_function */
911 "R_C6000_SBR_GOT_L16_W",/* name */
912 TRUE, /* partial_inplace */
913 0x007fff80, /* src_mask */
914 0x007fff80, /* dst_mask */
915 FALSE), /* pcrel_offset */
916 EMPTY_HOWTO (R_C6000_SBR_GOT_H16_W),
917 HOWTO (R_C6000_DSBT_INDEX, /* type */
919 2, /* size (0 = byte, 1 = short, 2 = long) */
921 FALSE, /* pc_relative */
923 complain_overflow_unsigned,/* complain_on_overflow */
924 bfd_elf_generic_reloc, /* special_function */
925 "R_C6000_DSBT_INDEX", /* name */
926 TRUE, /* partial_inplace */
928 0x007fff00, /* dst_mask */
929 FALSE), /* pcrel_offset */
930 HOWTO (R_C6000_PREL31, /* type */
932 2, /* size (0 = byte, 1 = short, 2 = long) */
934 FALSE, /* pc_relative */
936 complain_overflow_dont,/* complain_on_overflow */
937 bfd_elf_generic_reloc, /* special_function */
938 "R_C6000_PREL31", /* name */
939 TRUE, /* partial_inplace */
941 0x7fffffff, /* dst_mask */
942 FALSE), /* pcrel_offset */
943 HOWTO (R_C6000_COPY, /* type */
945 2, /* size (0 = byte, 1 = short, 2 = long) */
947 FALSE, /* pc_relative */
949 complain_overflow_dont,/* complain_on_overflow */
950 bfd_elf_generic_reloc, /* special_function */
951 "R_C6000_COPY", /* name */
952 TRUE, /* partial_inplace */
954 0xffffffff, /* dst_mask */
955 FALSE), /* pcrel_offset */
1182 HOWTO (R_C6000_ALIGN, /* type */
1184 0, /* size (0 = byte, 1 = short, 2 = long) */
1186 FALSE, /* pc_relative */
1188 complain_overflow_dont,/* complain_on_overflow */
1189 bfd_elf_generic_reloc, /* special_function */
1190 "R_C6000_ALIGN", /* name */
1191 TRUE, /* partial_inplace */
1194 FALSE), /* pcrel_offset */
1195 HOWTO (R_C6000_FPHEAD, /* type */
1197 0, /* size (0 = byte, 1 = short, 2 = long) */
1199 FALSE, /* pc_relative */
1201 complain_overflow_dont,/* complain_on_overflow */
1202 bfd_elf_generic_reloc, /* special_function */
1203 "R_C6000_FPHEAD", /* name */
1204 TRUE, /* partial_inplace */
1207 FALSE), /* pcrel_offset */
1208 HOWTO (R_C6000_NOCMP, /* type */
1210 0, /* size (0 = byte, 1 = short, 2 = long) */
1212 FALSE, /* pc_relative */
1214 complain_overflow_dont,/* complain_on_overflow */
1215 bfd_elf_generic_reloc, /* special_function */
1216 "R_C6000_NOCMP", /* name */
1217 TRUE, /* partial_inplace */
1220 FALSE) /* pcrel_offset */
1223 /* Map BFD relocations to ELF relocations. */
1227 bfd_reloc_code_real_type bfd_reloc_val;
1228 enum elf_tic6x_reloc_type elf_reloc_val;
1231 static const tic6x_reloc_map elf32_tic6x_reloc_map[] =
1233 { BFD_RELOC_NONE, R_C6000_NONE },
1234 { BFD_RELOC_32, R_C6000_ABS32 },
1235 { BFD_RELOC_16, R_C6000_ABS16 },
1236 { BFD_RELOC_8, R_C6000_ABS8 },
1237 { BFD_RELOC_C6000_PCR_S21, R_C6000_PCR_S21 },
1238 { BFD_RELOC_C6000_PCR_S12, R_C6000_PCR_S12 },
1239 { BFD_RELOC_C6000_PCR_S10, R_C6000_PCR_S10 },
1240 { BFD_RELOC_C6000_PCR_S7, R_C6000_PCR_S7 },
1241 { BFD_RELOC_C6000_ABS_S16, R_C6000_ABS_S16 },
1242 { BFD_RELOC_C6000_ABS_L16, R_C6000_ABS_L16 },
1243 { BFD_RELOC_C6000_ABS_H16, R_C6000_ABS_H16 },
1244 { BFD_RELOC_C6000_SBR_U15_B, R_C6000_SBR_U15_B },
1245 { BFD_RELOC_C6000_SBR_U15_H, R_C6000_SBR_U15_H },
1246 { BFD_RELOC_C6000_SBR_U15_W, R_C6000_SBR_U15_W },
1247 { BFD_RELOC_C6000_SBR_S16, R_C6000_SBR_S16 },
1248 { BFD_RELOC_C6000_SBR_L16_B, R_C6000_SBR_L16_B },
1249 { BFD_RELOC_C6000_SBR_L16_H, R_C6000_SBR_L16_H },
1250 { BFD_RELOC_C6000_SBR_L16_W, R_C6000_SBR_L16_W },
1251 { BFD_RELOC_C6000_SBR_H16_B, R_C6000_SBR_H16_B },
1252 { BFD_RELOC_C6000_SBR_H16_H, R_C6000_SBR_H16_H },
1253 { BFD_RELOC_C6000_SBR_H16_W, R_C6000_SBR_H16_W },
1254 { BFD_RELOC_C6000_SBR_GOT_U15_W, R_C6000_SBR_GOT_U15_W },
1255 { BFD_RELOC_C6000_SBR_GOT_L16_W, R_C6000_SBR_GOT_L16_W },
1256 { BFD_RELOC_C6000_SBR_GOT_H16_W, R_C6000_SBR_GOT_H16_W },
1257 { BFD_RELOC_C6000_DSBT_INDEX, R_C6000_DSBT_INDEX },
1258 { BFD_RELOC_C6000_PREL31, R_C6000_PREL31 },
1259 { BFD_RELOC_C6000_COPY, R_C6000_COPY },
1260 { BFD_RELOC_C6000_ALIGN, R_C6000_ALIGN },
1261 { BFD_RELOC_C6000_FPHEAD, R_C6000_FPHEAD },
1262 { BFD_RELOC_C6000_NOCMP, R_C6000_NOCMP }
1265 static reloc_howto_type *
1266 elf32_tic6x_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1270 for (i = 0; i < ARRAY_SIZE (elf32_tic6x_reloc_map); i++)
1271 if (elf32_tic6x_reloc_map[i].bfd_reloc_val == code)
1273 enum elf_tic6x_reloc_type elf_reloc_val;
1274 reloc_howto_type *howto;
1276 elf_reloc_val = elf32_tic6x_reloc_map[i].elf_reloc_val;
1277 if (elf32_tic6x_tdata (abfd)->use_rela_p)
1278 howto = &elf32_tic6x_howto_table[elf_reloc_val];
1280 howto = &elf32_tic6x_howto_table_rel[elf_reloc_val];
1282 /* Some relocations are RELA-only; do not return them for
1284 if (howto->name == NULL)
1293 static reloc_howto_type *
1294 elf32_tic6x_reloc_name_lookup (bfd *abfd, const char *r_name)
1296 if (elf32_tic6x_tdata (abfd)->use_rela_p)
1300 for (i = 0; i < ARRAY_SIZE (elf32_tic6x_howto_table); i++)
1301 if (elf32_tic6x_howto_table[i].name != NULL
1302 && strcasecmp (elf32_tic6x_howto_table[i].name, r_name) == 0)
1303 return &elf32_tic6x_howto_table[i];
1309 for (i = 0; i < ARRAY_SIZE (elf32_tic6x_howto_table_rel); i++)
1310 if (elf32_tic6x_howto_table_rel[i].name != NULL
1311 && strcasecmp (elf32_tic6x_howto_table_rel[i].name, r_name) == 0)
1312 return &elf32_tic6x_howto_table_rel[i];
1319 elf32_tic6x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
1320 Elf_Internal_Rela *elf_reloc)
1322 unsigned int r_type;
1324 r_type = ELF32_R_TYPE (elf_reloc->r_info);
1325 if (r_type >= ARRAY_SIZE (elf32_tic6x_howto_table))
1326 bfd_reloc->howto = NULL;
1328 bfd_reloc->howto = &elf32_tic6x_howto_table[r_type];
1332 elf32_tic6x_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
1333 Elf_Internal_Rela *elf_reloc)
1335 unsigned int r_type;
1337 r_type = ELF32_R_TYPE (elf_reloc->r_info);
1338 if (r_type >= ARRAY_SIZE (elf32_tic6x_howto_table_rel))
1339 bfd_reloc->howto = NULL;
1341 bfd_reloc->howto = &elf32_tic6x_howto_table_rel[r_type];
1345 elf32_tic6x_set_use_rela_p (bfd *abfd, bfd_boolean use_rela_p)
1347 elf32_tic6x_tdata (abfd)->use_rela_p = use_rela_p;
1351 elf32_tic6x_mkobject (bfd *abfd)
1355 ret = bfd_elf_allocate_object (abfd, sizeof (struct elf32_tic6x_obj_tdata),
1358 elf32_tic6x_set_use_rela_p (abfd, TRUE);
1363 elf32_tic6x_new_section_hook (bfd *abfd, asection *sec)
1367 ret = _bfd_elf_new_section_hook (abfd, sec);
1368 sec->use_rela_p = elf32_tic6x_tdata (abfd)->use_rela_p;
1373 /* Return true if relocation REL against section SEC is a REL rather
1374 than RELA relocation. RELOCS is the first relocation in the
1375 section and ABFD is the bfd that contains SEC. */
1378 elf32_tic6x_rel_relocation_p (bfd *abfd, asection *sec,
1379 const Elf_Internal_Rela *relocs,
1380 const Elf_Internal_Rela *rel)
1382 Elf_Internal_Shdr *rel_hdr;
1383 const struct elf_backend_data *bed;
1385 /* To determine which flavor of relocation this is, we depend on the
1386 fact that the INPUT_SECTION's REL_HDR is read before its
1388 rel_hdr = &elf_section_data (sec)->rel_hdr;
1389 bed = get_elf_backend_data (abfd);
1390 if ((size_t) (rel - relocs)
1391 >= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
1392 rel_hdr = elf_section_data (sec)->rel_hdr2;
1393 return rel_hdr->sh_entsize == bed->s->sizeof_rel;
1397 elf32_tic6x_relocate_section (bfd *output_bfd,
1398 struct bfd_link_info *info,
1400 asection *input_section,
1402 Elf_Internal_Rela *relocs,
1403 Elf_Internal_Sym *local_syms,
1404 asection **local_sections)
1406 Elf_Internal_Shdr *symtab_hdr;
1407 struct elf_link_hash_entry **sym_hashes;
1408 Elf_Internal_Rela *rel;
1409 Elf_Internal_Rela *relend;
1410 bfd_boolean ok = TRUE;
1412 symtab_hdr = & elf_symtab_hdr (input_bfd);
1413 sym_hashes = elf_sym_hashes (input_bfd);
1415 relend = relocs + input_section->reloc_count;
1417 for (rel = relocs; rel < relend; rel ++)
1420 unsigned long r_symndx;
1422 reloc_howto_type *howto;
1423 Elf_Internal_Sym *sym;
1425 struct elf_link_hash_entry *h;
1427 bfd_boolean unresolved_reloc;
1428 bfd_reloc_status_type r;
1429 struct bfd_link_hash_entry *sbh;
1432 r_type = ELF32_R_TYPE (rel->r_info);
1433 r_symndx = ELF32_R_SYM (rel->r_info);
1435 is_rel = elf32_tic6x_rel_relocation_p (input_bfd, input_section,
1439 elf32_tic6x_info_to_howto_rel (input_bfd, &bfd_reloc, rel);
1441 elf32_tic6x_info_to_howto (input_bfd, &bfd_reloc, rel);
1442 howto = bfd_reloc.howto;
1445 bfd_set_error (bfd_error_bad_value);
1452 unresolved_reloc = FALSE;
1454 if (r_symndx < symtab_hdr->sh_info)
1456 sym = local_syms + r_symndx;
1457 sec = local_sections[r_symndx];
1458 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1464 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1465 r_symndx, symtab_hdr, sym_hashes,
1467 unresolved_reloc, warned);
1470 if (sec != NULL && elf_discarded_section (sec))
1472 /* For relocs against symbols from removed linkonce sections,
1473 or sections discarded by a linker script, we just want the
1474 section contents zeroed. Avoid any special processing. */
1475 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
1481 if (info->relocatable)
1485 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1488 relocation = sec->output_offset + sym->st_value;
1489 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1490 contents + rel->r_offset);
1500 case R_C6000_FPHEAD:
1502 /* No action needed. */
1505 case R_C6000_PCR_S21:
1506 case R_C6000_PCR_S12:
1507 case R_C6000_PCR_S10:
1508 case R_C6000_PCR_S7:
1509 /* Generic PC-relative handling produces a value relative to
1510 the exact location of the relocation. Adjust it to be
1511 relative to the start of the fetch packet instead. */
1512 relocation += (input_section->output_section->vma
1513 + input_section->output_offset
1514 + rel->r_offset) & 0x1f;
1519 case R_C6000_ABS_S16:
1520 case R_C6000_ABS_L16:
1521 case R_C6000_ABS_H16:
1522 /* Generic logic OK. */
1525 case R_C6000_SBR_U15_B:
1526 case R_C6000_SBR_U15_H:
1527 case R_C6000_SBR_U15_W:
1528 case R_C6000_SBR_S16:
1529 case R_C6000_SBR_L16_B:
1530 case R_C6000_SBR_L16_H:
1531 case R_C6000_SBR_L16_W:
1532 case R_C6000_SBR_H16_B:
1533 case R_C6000_SBR_H16_H:
1534 case R_C6000_SBR_H16_W:
1535 sbh = bfd_link_hash_lookup (info->hash, "__c6xabi_DSBT_BASE",
1536 FALSE, FALSE, TRUE);
1538 && (sbh->type == bfd_link_hash_defined
1539 || sbh->type == bfd_link_hash_defweak))
1540 relocation -= (sbh->u.def.value
1541 + sbh->u.def.section->output_section->vma
1542 + sbh->u.def.section->output_offset);
1545 (*_bfd_error_handler) (_("%B: SB-relative relocation but "
1546 "__c6xabi_DSBT_BASE not defined"),
1553 case R_C6000_SBR_GOT_U15_W:
1554 case R_C6000_SBR_GOT_L16_W:
1555 case R_C6000_SBR_GOT_H16_W:
1556 case R_C6000_DSBT_INDEX:
1557 case R_C6000_PREL31:
1558 /* Shared libraries and exception handling support not
1560 (*_bfd_error_handler) (_("%B: relocation type %d not implemented"),
1566 /* Invalid in relocatable object. */
1568 /* Unknown relocation. */
1569 (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
1575 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1576 contents, rel->r_offset,
1577 relocation, rel->r_addend);
1580 if (r == bfd_reloc_ok
1581 && howto->complain_on_overflow == complain_overflow_bitfield)
1583 /* Generic overflow handling accepts cases the ABI says
1584 should be rejected for R_C6000_ABS16 and
1586 bfd_vma value = (relocation + rel->r_addend) & 0xffffffff;
1587 bfd_vma sbit = 1 << (howto->bitsize - 1);
1588 bfd_vma sbits = (-(bfd_vma) sbit) & 0xffffffff;
1589 bfd_vma value_sbits = value & sbits;
1591 if (value_sbits != 0
1592 && value_sbits != sbit
1593 && value_sbits != sbits)
1594 r = bfd_reloc_overflow;
1597 if (r != bfd_reloc_ok)
1600 const char *error_message;
1603 name = h->root.root.string;
1606 name = bfd_elf_string_from_elf_section (input_bfd,
1607 symtab_hdr->sh_link,
1612 name = bfd_section_name (input_bfd, sec);
1617 case bfd_reloc_overflow:
1618 /* If the overflowing reloc was to an undefined symbol,
1619 we have already printed one error message and there
1620 is no point complaining again. */
1622 h->root.type != bfd_link_hash_undefined)
1623 && (!((*info->callbacks->reloc_overflow)
1624 (info, (h ? &h->root : NULL), name, howto->name,
1625 (bfd_vma) 0, input_bfd, input_section,
1630 case bfd_reloc_undefined:
1631 if (!((*info->callbacks->undefined_symbol)
1632 (info, name, input_bfd, input_section,
1633 rel->r_offset, TRUE)))
1637 case bfd_reloc_outofrange:
1638 error_message = _("out of range");
1641 case bfd_reloc_notsupported:
1642 error_message = _("unsupported relocation");
1645 case bfd_reloc_dangerous:
1646 error_message = _("dangerous relocation");
1650 error_message = _("unknown error");
1654 BFD_ASSERT (error_message != NULL);
1655 if (!((*info->callbacks->reloc_dangerous)
1656 (info, error_message, input_bfd, input_section,
1668 #define TARGET_LITTLE_SYM bfd_elf32_tic6x_le_vec
1669 #define TARGET_LITTLE_NAME "elf32-tic6x-le"
1670 #define TARGET_BIG_SYM bfd_elf32_tic6x_be_vec
1671 #define TARGET_BIG_NAME "elf32-tic6x-be"
1672 #define ELF_ARCH bfd_arch_tic6x
1673 #define ELF_MACHINE_CODE EM_TI_C6000
1674 #define ELF_MAXPAGESIZE 1
1675 #define bfd_elf32_bfd_reloc_type_lookup elf32_tic6x_reloc_type_lookup
1676 #define bfd_elf32_bfd_reloc_name_lookup elf32_tic6x_reloc_name_lookup
1677 #define bfd_elf32_mkobject elf32_tic6x_mkobject
1678 #define bfd_elf32_new_section_hook elf32_tic6x_new_section_hook
1679 #define elf_backend_can_gc_sections 1
1680 #define elf_backend_default_use_rela_p 1
1681 #define elf_backend_may_use_rel_p 1
1682 #define elf_backend_may_use_rela_p 1
1683 #define elf_backend_rela_normal 1
1684 #define elf_backend_relocate_section elf32_tic6x_relocate_section
1685 #define elf_info_to_howto elf32_tic6x_info_to_howto
1686 #define elf_info_to_howto_rel elf32_tic6x_info_to_howto_rel
1688 #include "elf32-target.h"