bfd:
[external/binutils.git] / bfd / elf32-tic6x.c
1 /* 32-bit ELF support for TI C6X
2    Copyright 2010
3    Free Software Foundation, Inc.
4
5    This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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.  */
21
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "libiberty.h"
26 #include "elf-bfd.h"
27 #include "elf/tic6x.h"
28
29 static reloc_howto_type elf32_tic6x_howto_table[] =
30 {
31   HOWTO (R_C6000_NONE,          /* type */
32          0,                     /* rightshift */
33          0,                     /* size (0 = byte, 1 = short, 2 = long) */
34          0,                     /* bitsize */
35          FALSE,                 /* pc_relative */
36          0,                     /* bitpos */
37          complain_overflow_dont,/* complain_on_overflow */
38          bfd_elf_generic_reloc, /* special_function */
39          "R_C6000_NONE",        /* name */
40          FALSE,                 /* partial_inplace */
41          0,                     /* src_mask */
42          0,                     /* dst_mask */
43          FALSE),                /* pcrel_offset */
44   HOWTO (R_C6000_ABS32,         /* type */
45          0,                     /* rightshift */
46          2,                     /* size (0 = byte, 1 = short, 2 = long) */
47          32,                    /* bitsize */
48          FALSE,                 /* pc_relative */
49          0,                     /* bitpos */
50          complain_overflow_dont,/* complain_on_overflow */
51          bfd_elf_generic_reloc, /* special_function */
52          "R_C6000_ABS32",       /* name */
53          FALSE,                 /* partial_inplace */
54          0,                     /* src_mask */
55          0xffffffff,            /* dst_mask */
56          FALSE),                /* pcrel_offset */
57   HOWTO (R_C6000_ABS16,         /* type */
58          0,                     /* rightshift */
59          1,                     /* size (0 = byte, 1 = short, 2 = long) */
60          16,                    /* bitsize */
61          FALSE,                 /* pc_relative */
62          0,                     /* bitpos */
63          complain_overflow_bitfield,/* complain_on_overflow */
64          bfd_elf_generic_reloc, /* special_function */
65          "R_C6000_ABS16",       /* name */
66          FALSE,                 /* partial_inplace */
67          0,                     /* src_mask */
68          0x0000ffff,            /* dst_mask */
69          FALSE),                /* pcrel_offset */
70   HOWTO (R_C6000_ABS8,          /* type */
71          0,                     /* rightshift */
72          0,                     /* size (0 = byte, 1 = short, 2 = long) */
73          8,                     /* bitsize */
74          FALSE,                 /* pc_relative */
75          0,                     /* bitpos */
76          complain_overflow_bitfield,/* complain_on_overflow */
77          bfd_elf_generic_reloc, /* special_function */
78          "R_C6000_ABS8",        /* name */
79          FALSE,                 /* partial_inplace */
80          0,                     /* src_mask */
81          0x000000ff,            /* dst_mask */
82          FALSE),                /* pcrel_offset */
83   HOWTO (R_C6000_PCR_S21,       /* type */
84          2,                     /* rightshift */
85          2,                     /* size (0 = byte, 1 = short, 2 = long) */
86          21,                    /* bitsize */
87          TRUE,                  /* pc_relative */
88          7,                     /* bitpos */
89          complain_overflow_signed,/* complain_on_overflow */
90          bfd_elf_generic_reloc, /* special_function */
91          "R_C6000_PCR_S21",     /* name */
92          FALSE,                 /* partial_inplace */
93          0,                     /* src_mask */
94          0x0fffff80,            /* dst_mask */
95          TRUE),                 /* pcrel_offset */
96   HOWTO (R_C6000_PCR_S12,       /* type */
97          2,                     /* rightshift */
98          2,                     /* size (0 = byte, 1 = short, 2 = long) */
99          12,                    /* bitsize */
100          TRUE,                  /* pc_relative */
101          16,                    /* bitpos */
102          complain_overflow_signed,/* complain_on_overflow */
103          bfd_elf_generic_reloc, /* special_function */
104          "R_C6000_PCR_S12",     /* name */
105          FALSE,                 /* partial_inplace */
106          0,                     /* src_mask */
107          0x0fff0000,            /* dst_mask */
108          TRUE),                 /* pcrel_offset */
109   HOWTO (R_C6000_PCR_S10,       /* type */
110          2,                     /* rightshift */
111          2,                     /* size (0 = byte, 1 = short, 2 = long) */
112          10,                    /* bitsize */
113          TRUE,                  /* pc_relative */
114          13,                    /* bitpos */
115          complain_overflow_signed,/* complain_on_overflow */
116          bfd_elf_generic_reloc, /* special_function */
117          "R_C6000_PCR_S10",     /* name */
118          FALSE,                 /* partial_inplace */
119          0,                     /* src_mask */
120          0x007fe000,            /* dst_mask */
121          TRUE),                 /* pcrel_offset */
122   HOWTO (R_C6000_PCR_S7,        /* type */
123          2,                     /* rightshift */
124          2,                     /* size (0 = byte, 1 = short, 2 = long) */
125          7,                     /* bitsize */
126          TRUE,                  /* pc_relative */
127          16,                    /* bitpos */
128          complain_overflow_signed,/* complain_on_overflow */
129          bfd_elf_generic_reloc, /* special_function */
130          "R_C6000_PCR_S7",      /* name */
131          FALSE,                 /* partial_inplace */
132          0,                     /* src_mask */
133          0x007f0000,            /* dst_mask */
134          TRUE),                 /* pcrel_offset */
135   HOWTO (R_C6000_ABS_S16,       /* type */
136          0,                     /* rightshift */
137          2,                     /* size (0 = byte, 1 = short, 2 = long) */
138          16,                    /* bitsize */
139          FALSE,                 /* pc_relative */
140          7,                     /* bitpos */
141          complain_overflow_signed,/* complain_on_overflow */
142          bfd_elf_generic_reloc, /* special_function */
143          "R_C6000_ABS_S16",     /* name */
144          FALSE,                 /* partial_inplace */
145          0,                     /* src_mask */
146          0x007fff80,            /* dst_mask */
147          FALSE),                /* pcrel_offset */
148   HOWTO (R_C6000_ABS_L16,       /* type */
149          0,                     /* rightshift */
150          2,                     /* size (0 = byte, 1 = short, 2 = long) */
151          16,                    /* bitsize */
152          FALSE,                 /* pc_relative */
153          7,                     /* bitpos */
154          complain_overflow_dont,/* complain_on_overflow */
155          bfd_elf_generic_reloc, /* special_function */
156          "R_C6000_ABS_L16",     /* name */
157          FALSE,                 /* partial_inplace */
158          0,                     /* src_mask */
159          0x007fff80,            /* dst_mask */
160          FALSE),                /* pcrel_offset */
161   HOWTO (R_C6000_ABS_H16,       /* type */
162          16,                    /* rightshift */
163          2,                     /* size (0 = byte, 1 = short, 2 = long) */
164          16,                    /* bitsize */
165          FALSE,                 /* pc_relative */
166          7,                     /* bitpos */
167          complain_overflow_dont,/* complain_on_overflow */
168          bfd_elf_generic_reloc, /* special_function */
169          "R_C6000_ABS_H16",     /* name */
170          FALSE,                 /* partial_inplace */
171          0,                     /* src_mask */
172          0x007fff80,            /* dst_mask */
173          FALSE),                /* pcrel_offset */
174   HOWTO (R_C6000_SBR_U15_B,     /* type */
175          0,                     /* rightshift */
176          2,                     /* size (0 = byte, 1 = short, 2 = long) */
177          15,                    /* bitsize */
178          FALSE,                 /* pc_relative */
179          8,                     /* bitpos */
180          complain_overflow_unsigned,/* complain_on_overflow */
181          bfd_elf_generic_reloc, /* special_function */
182          "R_C6000_SBR_U15_B",   /* name */
183          FALSE,                 /* partial_inplace */
184          0,                     /* src_mask */
185          0x007fff00,            /* dst_mask */
186          FALSE),                /* pcrel_offset */
187   HOWTO (R_C6000_SBR_U15_H,     /* type */
188          1,                     /* rightshift */
189          2,                     /* size (0 = byte, 1 = short, 2 = long) */
190          15,                    /* bitsize */
191          FALSE,                 /* pc_relative */
192          8,                     /* bitpos */
193          complain_overflow_unsigned,/* complain_on_overflow */
194          bfd_elf_generic_reloc, /* special_function */
195          "R_C6000_SBR_U15_H",   /* name */
196          FALSE,                 /* partial_inplace */
197          0,                     /* src_mask */
198          0x007fff00,            /* dst_mask */
199          FALSE),                /* pcrel_offset */
200   HOWTO (R_C6000_SBR_U15_W,     /* type */
201          2,                     /* rightshift */
202          2,                     /* size (0 = byte, 1 = short, 2 = long) */
203          15,                    /* bitsize */
204          FALSE,                 /* pc_relative */
205          8,                     /* bitpos */
206          complain_overflow_unsigned,/* complain_on_overflow */
207          bfd_elf_generic_reloc, /* special_function */
208          "R_C6000_SBR_U15_W",   /* name */
209          FALSE,                 /* partial_inplace */
210          0,                     /* src_mask */
211          0x007fff00,            /* dst_mask */
212          FALSE),                /* pcrel_offset */
213   HOWTO (R_C6000_SBR_S16,       /* type */
214          0,                     /* rightshift */
215          2,                     /* size (0 = byte, 1 = short, 2 = long) */
216          16,                    /* bitsize */
217          FALSE,                 /* pc_relative */
218          7,                     /* bitpos */
219          complain_overflow_signed,/* complain_on_overflow */
220          bfd_elf_generic_reloc, /* special_function */
221          "R_C6000_SBR_S16",     /* name */
222          FALSE,                 /* partial_inplace */
223          0,                     /* src_mask */
224          0x007fff80,            /* dst_mask */
225          FALSE),                /* pcrel_offset */
226   HOWTO (R_C6000_SBR_L16_B,     /* type */
227          0,                     /* rightshift */
228          2,                     /* size (0 = byte, 1 = short, 2 = long) */
229          16,                    /* bitsize */
230          FALSE,                 /* pc_relative */
231          7,                     /* bitpos */
232          complain_overflow_dont,/* complain_on_overflow */
233          bfd_elf_generic_reloc, /* special_function */
234          "R_C6000_SBR_L16_B",   /* name */
235          FALSE,                 /* partial_inplace */
236          0,                     /* src_mask */
237          0x007fff80,            /* dst_mask */
238          FALSE),                /* pcrel_offset */
239   HOWTO (R_C6000_SBR_L16_H,     /* type */
240          1,                     /* rightshift */
241          2,                     /* size (0 = byte, 1 = short, 2 = long) */
242          16,                    /* bitsize */
243          FALSE,                 /* pc_relative */
244          7,                     /* bitpos */
245          complain_overflow_dont,/* complain_on_overflow */
246          bfd_elf_generic_reloc, /* special_function */
247          "R_C6000_SBR_L16_H",   /* name */
248          FALSE,                 /* partial_inplace */
249          0,                     /* src_mask */
250          0x007fff80,            /* dst_mask */
251          FALSE),                /* pcrel_offset */
252   HOWTO (R_C6000_SBR_L16_W,     /* type */
253          2,                     /* rightshift */
254          2,                     /* size (0 = byte, 1 = short, 2 = long) */
255          16,                    /* bitsize */
256          FALSE,                 /* pc_relative */
257          7,                     /* bitpos */
258          complain_overflow_dont,/* complain_on_overflow */
259          bfd_elf_generic_reloc, /* special_function */
260          "R_C6000_SBR_L16_W",   /* name */
261          FALSE,                 /* partial_inplace */
262          0,                     /* src_mask */
263          0x007fff80,            /* dst_mask */
264          FALSE),                /* pcrel_offset */
265   HOWTO (R_C6000_SBR_H16_B,     /* type */
266          16,                    /* rightshift */
267          2,                     /* size (0 = byte, 1 = short, 2 = long) */
268          16,                    /* bitsize */
269          FALSE,                 /* pc_relative */
270          7,                     /* bitpos */
271          complain_overflow_dont,/* complain_on_overflow */
272          bfd_elf_generic_reloc, /* special_function */
273          "R_C6000_SBR_H16_B",   /* name */
274          FALSE,                 /* partial_inplace */
275          0,                     /* src_mask */
276          0x007fff80,            /* dst_mask */
277          FALSE),                /* pcrel_offset */
278   HOWTO (R_C6000_SBR_H16_H,     /* type */
279          17,                    /* rightshift */
280          2,                     /* size (0 = byte, 1 = short, 2 = long) */
281          16,                    /* bitsize */
282          FALSE,                 /* pc_relative */
283          7,                     /* bitpos */
284          complain_overflow_dont,/* complain_on_overflow */
285          bfd_elf_generic_reloc, /* special_function */
286          "R_C6000_SBR_H16_H",   /* name */
287          FALSE,                 /* partial_inplace */
288          0,                     /* src_mask */
289          0x007fff80,            /* dst_mask */
290          FALSE),                /* pcrel_offset */
291   HOWTO (R_C6000_SBR_H16_W,     /* type */
292          18,                    /* rightshift */
293          2,                     /* size (0 = byte, 1 = short, 2 = long) */
294          16,                    /* bitsize */
295          FALSE,                 /* pc_relative */
296          7,                     /* bitpos */
297          complain_overflow_dont,/* complain_on_overflow */
298          bfd_elf_generic_reloc, /* special_function */
299          "R_C6000_SBR_H16_W",   /* name */
300          FALSE,                 /* partial_inplace */
301          0,                     /* src_mask */
302          0x007fff80,            /* dst_mask */
303          FALSE),                /* pcrel_offset */
304   HOWTO (R_C6000_SBR_GOT_U15_W, /* type */
305          2,                     /* rightshift */
306          2,                     /* size (0 = byte, 1 = short, 2 = long) */
307          15,                    /* bitsize */
308          FALSE,                 /* pc_relative */
309          8,                     /* bitpos */
310          complain_overflow_unsigned,/* complain_on_overflow */
311          bfd_elf_generic_reloc, /* special_function */
312          "R_C6000_SBR_GOT_U15_W",/* name */
313          FALSE,                 /* partial_inplace */
314          0,                     /* src_mask */
315          0x007fff00,            /* dst_mask */
316          FALSE),                /* pcrel_offset */
317   HOWTO (R_C6000_SBR_GOT_L16_W, /* type */
318          2,                     /* rightshift */
319          2,                     /* size (0 = byte, 1 = short, 2 = long) */
320          16,                    /* bitsize */
321          FALSE,                 /* pc_relative */
322          7,                     /* bitpos */
323          complain_overflow_dont,/* complain_on_overflow */
324          bfd_elf_generic_reloc, /* special_function */
325          "R_C6000_SBR_GOT_L16_W",/* name */
326          FALSE,                 /* partial_inplace */
327          0,                     /* src_mask */
328          0x007fff80,            /* dst_mask */
329          FALSE),                /* pcrel_offset */
330   HOWTO (R_C6000_SBR_GOT_H16_W, /* type */
331          18,                    /* rightshift */
332          2,                     /* size (0 = byte, 1 = short, 2 = long) */
333          16,                    /* bitsize */
334          FALSE,                 /* pc_relative */
335          7,                     /* bitpos */
336          complain_overflow_dont,/* complain_on_overflow */
337          bfd_elf_generic_reloc, /* special_function */
338          "R_C6000_SBR_GOT_H16_W",/* name */
339          FALSE,                 /* partial_inplace */
340          0,                     /* src_mask */
341          0x007fff80,            /* dst_mask */
342          FALSE),                /* pcrel_offset */
343   HOWTO (R_C6000_DSBT_INDEX,    /* type */
344          0,                     /* rightshift */
345          2,                     /* size (0 = byte, 1 = short, 2 = long) */
346          15,                    /* bitsize */
347          FALSE,                 /* pc_relative */
348          8,                     /* bitpos */
349          complain_overflow_unsigned,/* complain_on_overflow */
350          bfd_elf_generic_reloc, /* special_function */
351          "R_C6000_DSBT_INDEX",  /* name */
352          FALSE,                 /* partial_inplace */
353          0,                     /* src_mask */
354          0x007fff00,            /* dst_mask */
355          FALSE),                /* pcrel_offset */
356   HOWTO (R_C6000_PREL31,        /* type */
357          1,                     /* rightshift */
358          2,                     /* size (0 = byte, 1 = short, 2 = long) */
359          31,                    /* bitsize */
360          FALSE,                 /* pc_relative */
361          0,                     /* bitpos */
362          complain_overflow_dont,/* complain_on_overflow */
363          bfd_elf_generic_reloc, /* special_function */
364          "R_C6000_PREL31",      /* name */
365          FALSE,                 /* partial_inplace */
366          0,                     /* src_mask */
367          0x7fffffff,            /* dst_mask */
368          FALSE),                /* pcrel_offset */
369   HOWTO (R_C6000_COPY,          /* type */
370          0,                     /* rightshift */
371          2,                     /* size (0 = byte, 1 = short, 2 = long) */
372          32,                    /* bitsize */
373          FALSE,                 /* pc_relative */
374          0,                     /* bitpos */
375          complain_overflow_dont,/* complain_on_overflow */
376          bfd_elf_generic_reloc, /* special_function */
377          "R_C6000_COPY",        /* name */
378          FALSE,                 /* partial_inplace */
379          0,                     /* src_mask */
380          0xffffffff,            /* dst_mask */
381          FALSE),                /* pcrel_offset */
382   EMPTY_HOWTO (27),
383   EMPTY_HOWTO (28),
384   EMPTY_HOWTO (29),
385   EMPTY_HOWTO (30),
386   EMPTY_HOWTO (31),
387   EMPTY_HOWTO (32),
388   EMPTY_HOWTO (33),
389   EMPTY_HOWTO (34),
390   EMPTY_HOWTO (35),
391   EMPTY_HOWTO (36),
392   EMPTY_HOWTO (37),
393   EMPTY_HOWTO (38),
394   EMPTY_HOWTO (39),
395   EMPTY_HOWTO (40),
396   EMPTY_HOWTO (41),
397   EMPTY_HOWTO (42),
398   EMPTY_HOWTO (43),
399   EMPTY_HOWTO (44),
400   EMPTY_HOWTO (45),
401   EMPTY_HOWTO (46),
402   EMPTY_HOWTO (47),
403   EMPTY_HOWTO (48),
404   EMPTY_HOWTO (49),
405   EMPTY_HOWTO (50),
406   EMPTY_HOWTO (51),
407   EMPTY_HOWTO (52),
408   EMPTY_HOWTO (53),
409   EMPTY_HOWTO (54),
410   EMPTY_HOWTO (55),
411   EMPTY_HOWTO (56),
412   EMPTY_HOWTO (57),
413   EMPTY_HOWTO (58),
414   EMPTY_HOWTO (59),
415   EMPTY_HOWTO (60),
416   EMPTY_HOWTO (61),
417   EMPTY_HOWTO (62),
418   EMPTY_HOWTO (63),
419   EMPTY_HOWTO (64),
420   EMPTY_HOWTO (65),
421   EMPTY_HOWTO (66),
422   EMPTY_HOWTO (67),
423   EMPTY_HOWTO (68),
424   EMPTY_HOWTO (69),
425   EMPTY_HOWTO (70),
426   EMPTY_HOWTO (71),
427   EMPTY_HOWTO (72),
428   EMPTY_HOWTO (73),
429   EMPTY_HOWTO (74),
430   EMPTY_HOWTO (75),
431   EMPTY_HOWTO (76),
432   EMPTY_HOWTO (77),
433   EMPTY_HOWTO (78),
434   EMPTY_HOWTO (79),
435   EMPTY_HOWTO (80),
436   EMPTY_HOWTO (81),
437   EMPTY_HOWTO (82),
438   EMPTY_HOWTO (83),
439   EMPTY_HOWTO (84),
440   EMPTY_HOWTO (85),
441   EMPTY_HOWTO (86),
442   EMPTY_HOWTO (87),
443   EMPTY_HOWTO (88),
444   EMPTY_HOWTO (89),
445   EMPTY_HOWTO (90),
446   EMPTY_HOWTO (91),
447   EMPTY_HOWTO (92),
448   EMPTY_HOWTO (93),
449   EMPTY_HOWTO (94),
450   EMPTY_HOWTO (95),
451   EMPTY_HOWTO (96),
452   EMPTY_HOWTO (97),
453   EMPTY_HOWTO (98),
454   EMPTY_HOWTO (99),
455   EMPTY_HOWTO (100),
456   EMPTY_HOWTO (101),
457   EMPTY_HOWTO (102),
458   EMPTY_HOWTO (103),
459   EMPTY_HOWTO (104),
460   EMPTY_HOWTO (105),
461   EMPTY_HOWTO (106),
462   EMPTY_HOWTO (107),
463   EMPTY_HOWTO (108),
464   EMPTY_HOWTO (109),
465   EMPTY_HOWTO (110),
466   EMPTY_HOWTO (111),
467   EMPTY_HOWTO (112),
468   EMPTY_HOWTO (113),
469   EMPTY_HOWTO (114),
470   EMPTY_HOWTO (115),
471   EMPTY_HOWTO (116),
472   EMPTY_HOWTO (117),
473   EMPTY_HOWTO (118),
474   EMPTY_HOWTO (119),
475   EMPTY_HOWTO (120),
476   EMPTY_HOWTO (121),
477   EMPTY_HOWTO (122),
478   EMPTY_HOWTO (123),
479   EMPTY_HOWTO (124),
480   EMPTY_HOWTO (125),
481   EMPTY_HOWTO (126),
482   EMPTY_HOWTO (127),
483   EMPTY_HOWTO (128),
484   EMPTY_HOWTO (129),
485   EMPTY_HOWTO (130),
486   EMPTY_HOWTO (131),
487   EMPTY_HOWTO (132),
488   EMPTY_HOWTO (133),
489   EMPTY_HOWTO (134),
490   EMPTY_HOWTO (135),
491   EMPTY_HOWTO (136),
492   EMPTY_HOWTO (137),
493   EMPTY_HOWTO (138),
494   EMPTY_HOWTO (139),
495   EMPTY_HOWTO (140),
496   EMPTY_HOWTO (141),
497   EMPTY_HOWTO (142),
498   EMPTY_HOWTO (143),
499   EMPTY_HOWTO (144),
500   EMPTY_HOWTO (145),
501   EMPTY_HOWTO (146),
502   EMPTY_HOWTO (147),
503   EMPTY_HOWTO (148),
504   EMPTY_HOWTO (149),
505   EMPTY_HOWTO (150),
506   EMPTY_HOWTO (151),
507   EMPTY_HOWTO (152),
508   EMPTY_HOWTO (153),
509   EMPTY_HOWTO (154),
510   EMPTY_HOWTO (155),
511   EMPTY_HOWTO (156),
512   EMPTY_HOWTO (157),
513   EMPTY_HOWTO (158),
514   EMPTY_HOWTO (159),
515   EMPTY_HOWTO (160),
516   EMPTY_HOWTO (161),
517   EMPTY_HOWTO (162),
518   EMPTY_HOWTO (163),
519   EMPTY_HOWTO (164),
520   EMPTY_HOWTO (165),
521   EMPTY_HOWTO (166),
522   EMPTY_HOWTO (167),
523   EMPTY_HOWTO (168),
524   EMPTY_HOWTO (169),
525   EMPTY_HOWTO (170),
526   EMPTY_HOWTO (171),
527   EMPTY_HOWTO (172),
528   EMPTY_HOWTO (173),
529   EMPTY_HOWTO (174),
530   EMPTY_HOWTO (175),
531   EMPTY_HOWTO (176),
532   EMPTY_HOWTO (177),
533   EMPTY_HOWTO (178),
534   EMPTY_HOWTO (179),
535   EMPTY_HOWTO (180),
536   EMPTY_HOWTO (181),
537   EMPTY_HOWTO (182),
538   EMPTY_HOWTO (183),
539   EMPTY_HOWTO (184),
540   EMPTY_HOWTO (185),
541   EMPTY_HOWTO (186),
542   EMPTY_HOWTO (187),
543   EMPTY_HOWTO (188),
544   EMPTY_HOWTO (189),
545   EMPTY_HOWTO (190),
546   EMPTY_HOWTO (191),
547   EMPTY_HOWTO (192),
548   EMPTY_HOWTO (193),
549   EMPTY_HOWTO (194),
550   EMPTY_HOWTO (195),
551   EMPTY_HOWTO (196),
552   EMPTY_HOWTO (197),
553   EMPTY_HOWTO (198),
554   EMPTY_HOWTO (199),
555   EMPTY_HOWTO (200),
556   EMPTY_HOWTO (201),
557   EMPTY_HOWTO (202),
558   EMPTY_HOWTO (203),
559   EMPTY_HOWTO (204),
560   EMPTY_HOWTO (205),
561   EMPTY_HOWTO (206),
562   EMPTY_HOWTO (207),
563   EMPTY_HOWTO (208),
564   EMPTY_HOWTO (209),
565   EMPTY_HOWTO (210),
566   EMPTY_HOWTO (211),
567   EMPTY_HOWTO (212),
568   EMPTY_HOWTO (213),
569   EMPTY_HOWTO (214),
570   EMPTY_HOWTO (215),
571   EMPTY_HOWTO (216),
572   EMPTY_HOWTO (217),
573   EMPTY_HOWTO (218),
574   EMPTY_HOWTO (219),
575   EMPTY_HOWTO (220),
576   EMPTY_HOWTO (221),
577   EMPTY_HOWTO (222),
578   EMPTY_HOWTO (223),
579   EMPTY_HOWTO (224),
580   EMPTY_HOWTO (225),
581   EMPTY_HOWTO (226),
582   EMPTY_HOWTO (227),
583   EMPTY_HOWTO (228),
584   EMPTY_HOWTO (229),
585   EMPTY_HOWTO (230),
586   EMPTY_HOWTO (231),
587   EMPTY_HOWTO (232),
588   EMPTY_HOWTO (233),
589   EMPTY_HOWTO (234),
590   EMPTY_HOWTO (235),
591   EMPTY_HOWTO (236),
592   EMPTY_HOWTO (237),
593   EMPTY_HOWTO (238),
594   EMPTY_HOWTO (239),
595   EMPTY_HOWTO (240),
596   EMPTY_HOWTO (241),
597   EMPTY_HOWTO (242),
598   EMPTY_HOWTO (243),
599   EMPTY_HOWTO (244),
600   EMPTY_HOWTO (245),
601   EMPTY_HOWTO (246),
602   EMPTY_HOWTO (247),
603   EMPTY_HOWTO (248),
604   EMPTY_HOWTO (249),
605   EMPTY_HOWTO (250),
606   EMPTY_HOWTO (251),
607   EMPTY_HOWTO (252),
608   HOWTO (R_C6000_ALIGN,         /* type */
609          0,                     /* rightshift */
610          0,                     /* size (0 = byte, 1 = short, 2 = long) */
611          0,                     /* bitsize */
612          FALSE,                 /* pc_relative */
613          0,                     /* bitpos */
614          complain_overflow_dont,/* complain_on_overflow */
615          bfd_elf_generic_reloc, /* special_function */
616          "R_C6000_ALIGN",       /* name */
617          FALSE,                 /* partial_inplace */
618          0,                     /* src_mask */
619          0,                     /* dst_mask */
620          FALSE),                /* pcrel_offset */
621   HOWTO (R_C6000_FPHEAD,        /* type */
622          0,                     /* rightshift */
623          0,                     /* size (0 = byte, 1 = short, 2 = long) */
624          0,                     /* bitsize */
625          FALSE,                 /* pc_relative */
626          0,                     /* bitpos */
627          complain_overflow_dont,/* complain_on_overflow */
628          bfd_elf_generic_reloc, /* special_function */
629          "R_C6000_FPHEAD",      /* name */
630          FALSE,                 /* partial_inplace */
631          0,                     /* src_mask */
632          0,                     /* dst_mask */
633          FALSE),                /* pcrel_offset */
634   HOWTO (R_C6000_NOCMP,         /* type */
635          0,                     /* rightshift */
636          0,                     /* size (0 = byte, 1 = short, 2 = long) */
637          0,                     /* bitsize */
638          FALSE,                 /* pc_relative */
639          0,                     /* bitpos */
640          complain_overflow_dont,/* complain_on_overflow */
641          bfd_elf_generic_reloc, /* special_function */
642          "R_C6000_NOCMP",       /* name */
643          FALSE,                 /* partial_inplace */
644          0,                     /* src_mask */
645          0,                     /* dst_mask */
646          FALSE)                 /* pcrel_offset */
647 };
648
649 /* Map BFD relocations to ELF relocations.  */
650
651 typedef struct
652 {
653   bfd_reloc_code_real_type bfd_reloc_val;
654   enum elf_tic6x_reloc_type elf_reloc_val;
655 } tic6x_reloc_map;
656
657 static const tic6x_reloc_map elf32_tic6x_reloc_map[] =
658   {
659     { BFD_RELOC_NONE, R_C6000_NONE },
660     { BFD_RELOC_32, R_C6000_ABS32 },
661     { BFD_RELOC_16, R_C6000_ABS16 },
662     { BFD_RELOC_8, R_C6000_ABS8 },
663     { BFD_RELOC_C6000_PCR_S21, R_C6000_PCR_S21 },
664     { BFD_RELOC_C6000_PCR_S12, R_C6000_PCR_S12 },
665     { BFD_RELOC_C6000_PCR_S10, R_C6000_PCR_S10 },
666     { BFD_RELOC_C6000_PCR_S7, R_C6000_PCR_S7 },
667     { BFD_RELOC_C6000_ABS_S16, R_C6000_ABS_S16 },
668     { BFD_RELOC_C6000_ABS_L16, R_C6000_ABS_L16 },
669     { BFD_RELOC_C6000_ABS_H16, R_C6000_ABS_H16 },
670     { BFD_RELOC_C6000_SBR_U15_B, R_C6000_SBR_U15_B },
671     { BFD_RELOC_C6000_SBR_U15_H, R_C6000_SBR_U15_H },
672     { BFD_RELOC_C6000_SBR_U15_W, R_C6000_SBR_U15_W },
673     { BFD_RELOC_C6000_SBR_S16, R_C6000_SBR_S16 },
674     { BFD_RELOC_C6000_SBR_L16_B, R_C6000_SBR_L16_B },
675     { BFD_RELOC_C6000_SBR_L16_H, R_C6000_SBR_L16_H },
676     { BFD_RELOC_C6000_SBR_L16_W, R_C6000_SBR_L16_W },
677     { BFD_RELOC_C6000_SBR_H16_B, R_C6000_SBR_H16_B },
678     { BFD_RELOC_C6000_SBR_H16_H, R_C6000_SBR_H16_H },
679     { BFD_RELOC_C6000_SBR_H16_W, R_C6000_SBR_H16_W },
680     { BFD_RELOC_C6000_SBR_GOT_U15_W, R_C6000_SBR_GOT_U15_W },
681     { BFD_RELOC_C6000_SBR_GOT_L16_W, R_C6000_SBR_GOT_L16_W },
682     { BFD_RELOC_C6000_SBR_GOT_H16_W, R_C6000_SBR_GOT_H16_W },
683     { BFD_RELOC_C6000_DSBT_INDEX, R_C6000_DSBT_INDEX },
684     { BFD_RELOC_C6000_PREL31, R_C6000_PREL31 },
685     { BFD_RELOC_C6000_COPY, R_C6000_COPY },
686     { BFD_RELOC_C6000_ALIGN, R_C6000_ALIGN },
687     { BFD_RELOC_C6000_FPHEAD, R_C6000_FPHEAD },
688     { BFD_RELOC_C6000_NOCMP, R_C6000_NOCMP }
689   };
690
691 static reloc_howto_type *
692 elf32_tic6x_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
693                                bfd_reloc_code_real_type code)
694 {
695   unsigned int i;
696
697   for (i = 0; i < ARRAY_SIZE (elf32_tic6x_reloc_map); i++)
698     if (elf32_tic6x_reloc_map[i].bfd_reloc_val == code)
699       return &elf32_tic6x_howto_table[elf32_tic6x_reloc_map[i].elf_reloc_val];
700
701   return NULL;
702 }
703
704 static reloc_howto_type *
705 elf32_tic6x_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
706 {
707   unsigned int i;
708
709   for (i = 0; i < ARRAY_SIZE (elf32_tic6x_howto_table); i++)
710     if (elf32_tic6x_howto_table[i].name != NULL
711         && strcasecmp (elf32_tic6x_howto_table[i].name, r_name) == 0)
712       return &elf32_tic6x_howto_table[i];
713
714   return NULL;
715 }
716
717 static void
718 elf32_tic6x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
719                            Elf_Internal_Rela *elf_reloc)
720 {
721   unsigned int r_type;
722
723   r_type = ELF32_R_TYPE (elf_reloc->r_info);
724   if (r_type >= ARRAY_SIZE (elf32_tic6x_howto_table))
725     bfd_reloc->howto = NULL;
726   else
727     bfd_reloc->howto = &elf32_tic6x_howto_table[r_type];
728 }
729
730 static bfd_boolean
731 elf32_tic6x_relocate_section (bfd *output_bfd,
732                               struct bfd_link_info *info,
733                               bfd *input_bfd,
734                               asection *input_section,
735                               bfd_byte *contents,
736                               Elf_Internal_Rela *relocs,
737                               Elf_Internal_Sym *local_syms,
738                               asection **local_sections)
739 {
740   Elf_Internal_Shdr *symtab_hdr;
741   struct elf_link_hash_entry **sym_hashes;
742   Elf_Internal_Rela *rel;
743   Elf_Internal_Rela *relend;
744   bfd_boolean ok = TRUE;
745
746   symtab_hdr = & elf_symtab_hdr (input_bfd);
747   sym_hashes = elf_sym_hashes (input_bfd);
748
749   relend = relocs + input_section->reloc_count;
750
751   for (rel = relocs; rel < relend; rel ++)
752     {
753       int r_type;
754       unsigned long r_symndx;
755       arelent bfd_reloc;
756       reloc_howto_type *howto;
757       Elf_Internal_Sym *sym;
758       asection *sec;
759       struct elf_link_hash_entry *h;
760       bfd_vma relocation;
761       bfd_boolean unresolved_reloc;
762       bfd_reloc_status_type r;
763       struct bfd_link_hash_entry *sbh;
764
765       r_type = ELF32_R_TYPE (rel->r_info);
766       r_symndx = ELF32_R_SYM (rel->r_info);
767
768       elf32_tic6x_info_to_howto (input_bfd, &bfd_reloc, rel);
769       howto = bfd_reloc.howto;
770       if (howto == NULL)
771         {
772           bfd_set_error (bfd_error_bad_value);
773           return FALSE;
774         }
775
776       h = NULL;
777       sym = NULL;
778       sec = NULL;
779       unresolved_reloc = FALSE;
780
781       if (r_symndx < symtab_hdr->sh_info)
782         {
783           sym = local_syms + r_symndx;
784           sec = local_sections[r_symndx];
785           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
786         }
787       else
788         {
789           bfd_boolean warned;
790
791           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
792                                    r_symndx, symtab_hdr, sym_hashes,
793                                    h, sec, relocation,
794                                    unresolved_reloc, warned);
795         }
796
797       if (sec != NULL && elf_discarded_section (sec))
798         {
799           /* For relocs against symbols from removed linkonce sections,
800              or sections discarded by a linker script, we just want the
801              section contents zeroed.  Avoid any special processing.  */
802           _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
803           rel->r_info = 0;
804           rel->r_addend = 0;
805           continue;
806         }
807
808       if (info->relocatable)
809         continue;
810
811       switch (r_type)
812         {
813         case R_C6000_NONE:
814         case R_C6000_ALIGN:
815         case R_C6000_FPHEAD:
816         case R_C6000_NOCMP:
817           /* No action needed.  */
818           continue;
819
820         case R_C6000_PCR_S21:
821         case R_C6000_PCR_S12:
822         case R_C6000_PCR_S10:
823         case R_C6000_PCR_S7:
824           /* Generic PC-relative handling produces a value relative to
825              the exact location of the relocation.  Adjust it to be
826              relative to the start of the fetch packet instead.  */
827           relocation += (input_section->output_section->vma
828                          + input_section->output_offset
829                          + rel->r_offset) & 0x1f;
830           /* Fall through.  */
831         case R_C6000_ABS32:
832         case R_C6000_ABS16:
833         case R_C6000_ABS8:
834         case R_C6000_ABS_S16:
835         case R_C6000_ABS_L16:
836         case R_C6000_ABS_H16:
837           /* Generic logic OK.  */
838           break;
839
840         case R_C6000_SBR_U15_B:
841         case R_C6000_SBR_U15_H:
842         case R_C6000_SBR_U15_W:
843         case R_C6000_SBR_S16:
844         case R_C6000_SBR_L16_B:
845         case R_C6000_SBR_L16_H:
846         case R_C6000_SBR_L16_W:
847         case R_C6000_SBR_H16_B:
848         case R_C6000_SBR_H16_H:
849         case R_C6000_SBR_H16_W:
850           sbh = bfd_link_hash_lookup (info->hash, "__c6xabi_DSBT_BASE",
851                                       FALSE, FALSE, TRUE);
852           if (sbh != NULL
853               && (sbh->type == bfd_link_hash_defined
854                   || sbh->type == bfd_link_hash_defweak))
855             relocation -= (sbh->u.def.value
856                            + sbh->u.def.section->output_section->vma
857                            + sbh->u.def.section->output_offset);
858           else
859             {
860               (*_bfd_error_handler) (_("%B: SB-relative relocation but "
861                                        "__c6xabi_DSBT_BASE not defined"),
862                                      input_bfd);
863               ok = FALSE;
864               continue;
865             }
866           break;
867
868         case R_C6000_SBR_GOT_U15_W:
869         case R_C6000_SBR_GOT_L16_W:
870         case R_C6000_SBR_GOT_H16_W:
871         case R_C6000_DSBT_INDEX:
872         case R_C6000_PREL31:
873           /* Shared libraries and exception handling support not
874              implemented.  */
875           (*_bfd_error_handler) (_("%B: relocation type %d not implemented"),
876                                  input_bfd, r_type);
877           ok = FALSE;
878           continue;
879
880         case R_C6000_COPY:
881           /* Invalid in relocatable object.  */
882         default:
883           /* Unknown relocation.  */
884           (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
885                                  input_bfd, r_type);
886           ok = FALSE;
887           continue;
888         }
889
890       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
891                                     contents, rel->r_offset,
892                                     relocation, rel->r_addend);
893
894       if (r == bfd_reloc_ok
895           && howto->complain_on_overflow == complain_overflow_bitfield)
896         {
897           /* Generic overflow handling accepts cases the ABI says
898              should be rejected for R_C6000_ABS16 and
899              R_C6000_ABS8.  */
900           bfd_vma value = (relocation + rel->r_addend) & 0xffffffff;
901           bfd_vma sbit = 1 << (howto->bitsize - 1);
902           bfd_vma sbits = (-(bfd_vma) sbit) & 0xffffffff;
903           bfd_vma value_sbits = value & sbits;
904
905           if (value_sbits != 0
906               && value_sbits != sbit
907               && value_sbits != sbits)
908             r = bfd_reloc_overflow;
909         }
910
911       if (r != bfd_reloc_ok)
912         {
913           const char *name;
914           const char *error_message;
915
916           if (h != NULL)
917             name = h->root.root.string;
918           else
919             {
920               name = bfd_elf_string_from_elf_section (input_bfd,
921                                                       symtab_hdr->sh_link,
922                                                       sym->st_name);
923               if (name == NULL)
924                 return FALSE;
925               if (*name == '\0')
926                 name = bfd_section_name (input_bfd, sec);
927             }
928
929           switch (r)
930             {
931             case bfd_reloc_overflow:
932               /* If the overflowing reloc was to an undefined symbol,
933                  we have already printed one error message and there
934                  is no point complaining again.  */
935               if ((! h ||
936                    h->root.type != bfd_link_hash_undefined)
937                   && (!((*info->callbacks->reloc_overflow)
938                         (info, (h ? &h->root : NULL), name, howto->name,
939                          (bfd_vma) 0, input_bfd, input_section,
940                          rel->r_offset))))
941                   return FALSE;
942               break;
943
944             case bfd_reloc_undefined:
945               if (!((*info->callbacks->undefined_symbol)
946                     (info, name, input_bfd, input_section,
947                      rel->r_offset, TRUE)))
948                 return FALSE;
949               break;
950
951             case bfd_reloc_outofrange:
952               error_message = _("out of range");
953               goto common_error;
954
955             case bfd_reloc_notsupported:
956               error_message = _("unsupported relocation");
957               goto common_error;
958
959             case bfd_reloc_dangerous:
960               error_message = _("dangerous relocation");
961               goto common_error;
962
963             default:
964               error_message = _("unknown error");
965               /* Fall through.  */
966
967             common_error:
968               BFD_ASSERT (error_message != NULL);
969               if (!((*info->callbacks->reloc_dangerous)
970                     (info, error_message, input_bfd, input_section,
971                      rel->r_offset)))
972                 return FALSE;
973               break;
974             }
975         }
976     }
977
978   return ok;
979 }
980
981
982 #define TARGET_LITTLE_SYM       bfd_elf32_tic6x_le_vec
983 #define TARGET_LITTLE_NAME      "elf32-tic6x-le"
984 #define TARGET_BIG_SYM          bfd_elf32_tic6x_be_vec
985 #define TARGET_BIG_NAME         "elf32-tic6x-be"
986 #define ELF_ARCH                bfd_arch_tic6x
987 #define ELF_MACHINE_CODE        EM_TI_C6000
988 #define ELF_MAXPAGESIZE         1
989 #define bfd_elf32_bfd_reloc_type_lookup elf32_tic6x_reloc_type_lookup
990 #define bfd_elf32_bfd_reloc_name_lookup elf32_tic6x_reloc_name_lookup
991 #define elf_backend_can_gc_sections     1
992 #define elf_backend_default_use_rela_p  1
993 #define elf_backend_may_use_rel_p       1
994 #define elf_backend_may_use_rela_p      1
995 #define elf_backend_rela_normal         1
996 #define elf_backend_relocate_section    elf32_tic6x_relocate_section
997 #define elf_info_to_howto               elf32_tic6x_info_to_howto
998 #define elf_info_to_howto_rel           _bfd_elf_no_info_to_howto
999
1000 #include "elf32-target.h"