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_fake_sections (bfd *abfd,
1352 Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
1355 /* The generic elf_fake_sections will set up REL_HDR using the
1356 default kind of relocations. But, we may actually need both
1357 kinds of relocations, so we set up the second header here. */
1358 if ((sec->flags & SEC_RELOC) != 0)
1360 struct bfd_elf_section_data *esd;
1361 bfd_size_type amt = sizeof (Elf_Internal_Shdr);
1363 esd = elf_section_data (sec);
1364 BFD_ASSERT (esd->rel_hdr2 == NULL);
1365 esd->rel_hdr2 = bfd_zalloc (abfd, amt);
1368 _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
1376 elf32_tic6x_mkobject (bfd *abfd)
1380 ret = bfd_elf_allocate_object (abfd, sizeof (struct elf32_tic6x_obj_tdata),
1383 elf32_tic6x_set_use_rela_p (abfd, TRUE);
1388 elf32_tic6x_new_section_hook (bfd *abfd, asection *sec)
1392 ret = _bfd_elf_new_section_hook (abfd, sec);
1393 sec->use_rela_p = elf32_tic6x_tdata (abfd)->use_rela_p;
1398 /* Return true if relocation REL against section SEC is a REL rather
1399 than RELA relocation. RELOCS is the first relocation in the
1400 section and ABFD is the bfd that contains SEC. */
1403 elf32_tic6x_rel_relocation_p (bfd *abfd, asection *sec,
1404 const Elf_Internal_Rela *relocs,
1405 const Elf_Internal_Rela *rel)
1407 Elf_Internal_Shdr *rel_hdr;
1408 const struct elf_backend_data *bed;
1410 /* To determine which flavor of relocation this is, we depend on the
1411 fact that the INPUT_SECTION's REL_HDR is read before its
1413 rel_hdr = &elf_section_data (sec)->rel_hdr;
1414 bed = get_elf_backend_data (abfd);
1415 if ((size_t) (rel - relocs)
1416 >= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
1417 rel_hdr = elf_section_data (sec)->rel_hdr2;
1418 return rel_hdr->sh_entsize == bed->s->sizeof_rel;
1422 elf32_tic6x_relocate_section (bfd *output_bfd,
1423 struct bfd_link_info *info,
1425 asection *input_section,
1427 Elf_Internal_Rela *relocs,
1428 Elf_Internal_Sym *local_syms,
1429 asection **local_sections)
1431 Elf_Internal_Shdr *symtab_hdr;
1432 struct elf_link_hash_entry **sym_hashes;
1433 Elf_Internal_Rela *rel;
1434 Elf_Internal_Rela *relend;
1435 bfd_boolean ok = TRUE;
1437 symtab_hdr = & elf_symtab_hdr (input_bfd);
1438 sym_hashes = elf_sym_hashes (input_bfd);
1440 relend = relocs + input_section->reloc_count;
1442 for (rel = relocs; rel < relend; rel ++)
1445 unsigned long r_symndx;
1447 reloc_howto_type *howto;
1448 Elf_Internal_Sym *sym;
1450 struct elf_link_hash_entry *h;
1452 bfd_boolean unresolved_reloc;
1453 bfd_reloc_status_type r;
1454 struct bfd_link_hash_entry *sbh;
1457 r_type = ELF32_R_TYPE (rel->r_info);
1458 r_symndx = ELF32_R_SYM (rel->r_info);
1460 is_rel = elf32_tic6x_rel_relocation_p (input_bfd, input_section,
1464 elf32_tic6x_info_to_howto_rel (input_bfd, &bfd_reloc, rel);
1466 elf32_tic6x_info_to_howto (input_bfd, &bfd_reloc, rel);
1467 howto = bfd_reloc.howto;
1470 bfd_set_error (bfd_error_bad_value);
1477 unresolved_reloc = FALSE;
1479 if (r_symndx < symtab_hdr->sh_info)
1481 sym = local_syms + r_symndx;
1482 sec = local_sections[r_symndx];
1483 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1489 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1490 r_symndx, symtab_hdr, sym_hashes,
1492 unresolved_reloc, warned);
1495 if (sec != NULL && elf_discarded_section (sec))
1497 /* For relocs against symbols from removed linkonce sections,
1498 or sections discarded by a linker script, we just want the
1499 section contents zeroed. Avoid any special processing. */
1500 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
1506 if (info->relocatable)
1510 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1513 relocation = sec->output_offset + sym->st_value;
1514 r = _bfd_relocate_contents (howto, input_bfd, relocation,
1515 contents + rel->r_offset);
1525 case R_C6000_FPHEAD:
1527 /* No action needed. */
1530 case R_C6000_PCR_S21:
1531 case R_C6000_PCR_S12:
1532 case R_C6000_PCR_S10:
1533 case R_C6000_PCR_S7:
1534 /* Generic PC-relative handling produces a value relative to
1535 the exact location of the relocation. Adjust it to be
1536 relative to the start of the fetch packet instead. */
1537 relocation += (input_section->output_section->vma
1538 + input_section->output_offset
1539 + rel->r_offset) & 0x1f;
1544 case R_C6000_ABS_S16:
1545 case R_C6000_ABS_L16:
1546 case R_C6000_ABS_H16:
1547 /* Generic logic OK. */
1550 case R_C6000_SBR_U15_B:
1551 case R_C6000_SBR_U15_H:
1552 case R_C6000_SBR_U15_W:
1553 case R_C6000_SBR_S16:
1554 case R_C6000_SBR_L16_B:
1555 case R_C6000_SBR_L16_H:
1556 case R_C6000_SBR_L16_W:
1557 case R_C6000_SBR_H16_B:
1558 case R_C6000_SBR_H16_H:
1559 case R_C6000_SBR_H16_W:
1560 sbh = bfd_link_hash_lookup (info->hash, "__c6xabi_DSBT_BASE",
1561 FALSE, FALSE, TRUE);
1563 && (sbh->type == bfd_link_hash_defined
1564 || sbh->type == bfd_link_hash_defweak))
1565 relocation -= (sbh->u.def.value
1566 + sbh->u.def.section->output_section->vma
1567 + sbh->u.def.section->output_offset);
1570 (*_bfd_error_handler) (_("%B: SB-relative relocation but "
1571 "__c6xabi_DSBT_BASE not defined"),
1578 case R_C6000_SBR_GOT_U15_W:
1579 case R_C6000_SBR_GOT_L16_W:
1580 case R_C6000_SBR_GOT_H16_W:
1581 case R_C6000_DSBT_INDEX:
1582 case R_C6000_PREL31:
1583 /* Shared libraries and exception handling support not
1585 (*_bfd_error_handler) (_("%B: relocation type %d not implemented"),
1591 /* Invalid in relocatable object. */
1593 /* Unknown relocation. */
1594 (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
1600 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1601 contents, rel->r_offset,
1602 relocation, rel->r_addend);
1605 if (r == bfd_reloc_ok
1606 && howto->complain_on_overflow == complain_overflow_bitfield)
1608 /* Generic overflow handling accepts cases the ABI says
1609 should be rejected for R_C6000_ABS16 and
1611 bfd_vma value = (relocation + rel->r_addend) & 0xffffffff;
1612 bfd_vma sbit = 1 << (howto->bitsize - 1);
1613 bfd_vma sbits = (-(bfd_vma) sbit) & 0xffffffff;
1614 bfd_vma value_sbits = value & sbits;
1616 if (value_sbits != 0
1617 && value_sbits != sbit
1618 && value_sbits != sbits)
1619 r = bfd_reloc_overflow;
1622 if (r != bfd_reloc_ok)
1625 const char *error_message;
1628 name = h->root.root.string;
1631 name = bfd_elf_string_from_elf_section (input_bfd,
1632 symtab_hdr->sh_link,
1637 name = bfd_section_name (input_bfd, sec);
1642 case bfd_reloc_overflow:
1643 /* If the overflowing reloc was to an undefined symbol,
1644 we have already printed one error message and there
1645 is no point complaining again. */
1647 h->root.type != bfd_link_hash_undefined)
1648 && (!((*info->callbacks->reloc_overflow)
1649 (info, (h ? &h->root : NULL), name, howto->name,
1650 (bfd_vma) 0, input_bfd, input_section,
1655 case bfd_reloc_undefined:
1656 if (!((*info->callbacks->undefined_symbol)
1657 (info, name, input_bfd, input_section,
1658 rel->r_offset, TRUE)))
1662 case bfd_reloc_outofrange:
1663 error_message = _("out of range");
1666 case bfd_reloc_notsupported:
1667 error_message = _("unsupported relocation");
1670 case bfd_reloc_dangerous:
1671 error_message = _("dangerous relocation");
1675 error_message = _("unknown error");
1679 BFD_ASSERT (error_message != NULL);
1680 if (!((*info->callbacks->reloc_dangerous)
1681 (info, error_message, input_bfd, input_section,
1693 elf32_tic6x_obj_attrs_arg_type (int tag)
1695 if (tag == Tag_compatibility)
1696 return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
1698 /* Correct for known attributes, arbitrary for others. */
1699 return ATTR_TYPE_FLAG_INT_VAL;
1702 /* Merge the Tag_C6XABI_Tag_CPU_arch attribute values ARCH1 and ARCH2
1703 and return the merged value. At present, all merges succeed, so no
1704 return value for errors is defined. */
1707 elf32_tic6x_merge_arch_attributes (int arch1, int arch2)
1709 int min_arch, max_arch;
1711 min_arch = (arch1 < arch2 ? arch1 : arch2);
1712 max_arch = (arch1 > arch2 ? arch1 : arch2);
1714 /* In most cases, the numerically greatest value is the correct
1715 merged value, but merging C64 and C67 results in C674X. */
1716 if ((min_arch == C6XABI_Tag_CPU_arch_C67X
1717 || min_arch == C6XABI_Tag_CPU_arch_C67XP)
1718 && (max_arch == C6XABI_Tag_CPU_arch_C64X
1719 || max_arch == C6XABI_Tag_CPU_arch_C64XP))
1720 return C6XABI_Tag_CPU_arch_C674X;
1725 /* Merge attributes from IBFD and OBFD, returning TRUE if the merge
1726 succeeded, FALSE otherwise. */
1729 elf32_tic6x_merge_attributes (bfd *ibfd, bfd *obfd)
1731 obj_attribute *in_attr;
1732 obj_attribute *out_attr;
1734 if (!elf_known_obj_attributes_proc (obfd)[0].i)
1736 /* This is the first object. Copy the attributes. */
1737 _bfd_elf_copy_obj_attributes (ibfd, obfd);
1739 out_attr = elf_known_obj_attributes_proc (obfd);
1741 /* Use the Tag_null value to indicate the attributes have been
1748 in_attr = elf_known_obj_attributes_proc (ibfd);
1749 out_attr = elf_known_obj_attributes_proc (obfd);
1751 /* No specification yet for handling of unknown attributes, so just
1752 ignore them and handle known ones. */
1753 out_attr[Tag_C6XABI_Tag_CPU_arch].i
1754 = elf32_tic6x_merge_arch_attributes (in_attr[Tag_C6XABI_Tag_CPU_arch].i,
1755 out_attr[Tag_C6XABI_Tag_CPU_arch].i);
1757 /* Merge Tag_compatibility attributes and any common GNU ones. */
1758 _bfd_elf_merge_object_attributes (ibfd, obfd);
1764 elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1766 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1769 if (!elf32_tic6x_merge_attributes (ibfd, obfd))
1776 #define TARGET_LITTLE_SYM bfd_elf32_tic6x_le_vec
1777 #define TARGET_LITTLE_NAME "elf32-tic6x-le"
1778 #define TARGET_BIG_SYM bfd_elf32_tic6x_be_vec
1779 #define TARGET_BIG_NAME "elf32-tic6x-be"
1780 #define ELF_ARCH bfd_arch_tic6x
1781 #define ELF_TARGET_ID TIC6X_ELF_DATA
1782 #define ELF_MACHINE_CODE EM_TI_C6000
1783 #define ELF_MAXPAGESIZE 1
1784 #define bfd_elf32_bfd_reloc_type_lookup elf32_tic6x_reloc_type_lookup
1785 #define bfd_elf32_bfd_reloc_name_lookup elf32_tic6x_reloc_name_lookup
1786 #define bfd_elf32_bfd_merge_private_bfd_data elf32_tic6x_merge_private_bfd_data
1787 #define bfd_elf32_mkobject elf32_tic6x_mkobject
1788 #define bfd_elf32_new_section_hook elf32_tic6x_new_section_hook
1789 #define elf_backend_can_gc_sections 1
1790 #define elf_backend_default_use_rela_p 1
1791 #define elf_backend_may_use_rel_p 1
1792 #define elf_backend_may_use_rela_p 1
1793 #define elf_backend_fake_sections elf32_tic6x_fake_sections
1794 #define elf_backend_obj_attrs_arg_type elf32_tic6x_obj_attrs_arg_type
1795 #define elf_backend_obj_attrs_section "__TI_build_attributes"
1796 #define elf_backend_obj_attrs_section_type SHT_C6000_ATTRIBUTES
1797 #define elf_backend_obj_attrs_vendor "c6xabi"
1798 #define elf_backend_rela_normal 1
1799 #define elf_backend_relocate_section elf32_tic6x_relocate_section
1800 #define elf_info_to_howto elf32_tic6x_info_to_howto
1801 #define elf_info_to_howto_rel elf32_tic6x_info_to_howto_rel
1803 #include "elf32-target.h"