unrecognized/unsupported reloc message
[external/binutils.git] / bfd / elf32-cr16c.c
1 /* BFD back-end for National Semiconductor's CR16C ELF
2    Copyright (C) 2004-2018 Free Software Foundation, Inc.
3
4    This file is part of BFD, the Binary File Descriptor library.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "libbfd.h"
24 #include "bfdlink.h"
25 #include "elf/cr16c.h"
26 #include "elf-bfd.h"
27
28
29 #define USE_REL 1       /* CR16C uses REL relocations instead of RELA.  */
30
31 /* The following definition is based on EMPTY_HOWTO macro,
32    but also initiates the "name" field in HOWTO struct.  */
33 #define ONLY_NAME_HOWTO(C) \
34   HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
35           STRINGX(C), FALSE, 0, 0, FALSE)
36
37 /* reloc_map_index array maps CRASM relocation type into a BFD
38    relocation enum. The array's indices are synchronized with
39    RINDEX_16C_* indices, created in include/elf/cr16c.h.
40    The array is used in:
41    1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup().
42    2. asreloc.c : find_reloc_type(). */
43
44 RELOC_MAP reloc_map_index[RINDEX_16C_MAX] =
45 {
46   {R_16C_NUM08,     BFD_RELOC_16C_NUM08},
47   {R_16C_NUM08_C,   BFD_RELOC_16C_NUM08_C},
48   {R_16C_NUM16,     BFD_RELOC_16C_NUM16},
49   {R_16C_NUM16_C,   BFD_RELOC_16C_NUM16_C},
50   {R_16C_NUM32,     BFD_RELOC_16C_NUM32},
51   {R_16C_NUM32_C,   BFD_RELOC_16C_NUM32_C},
52   {R_16C_DISP04,    BFD_RELOC_16C_DISP04},
53   {R_16C_DISP04_C,  BFD_RELOC_16C_DISP04_C},
54   {R_16C_DISP08,    BFD_RELOC_16C_DISP08},
55   {R_16C_DISP08_C,  BFD_RELOC_16C_DISP08_C},
56   {R_16C_DISP16,    BFD_RELOC_16C_DISP16},
57   {R_16C_DISP16_C,  BFD_RELOC_16C_DISP16_C},
58   {R_16C_DISP24,    BFD_RELOC_16C_DISP24},
59   {R_16C_DISP24_C,  BFD_RELOC_16C_DISP24_C},
60   {R_16C_DISP24a,   BFD_RELOC_16C_DISP24a},
61   {R_16C_DISP24a_C, BFD_RELOC_16C_DISP24a_C},
62   {R_16C_REG04,     BFD_RELOC_16C_REG04},
63   {R_16C_REG04_C,   BFD_RELOC_16C_REG04_C},
64   {R_16C_REG04a,    BFD_RELOC_16C_REG04a},
65   {R_16C_REG04a_C,  BFD_RELOC_16C_REG04a_C},
66   {R_16C_REG14,     BFD_RELOC_16C_REG14},
67   {R_16C_REG14_C,   BFD_RELOC_16C_REG14_C},
68   {R_16C_REG16,     BFD_RELOC_16C_REG16},
69   {R_16C_REG16_C,   BFD_RELOC_16C_REG16_C},
70   {R_16C_REG20,     BFD_RELOC_16C_REG20},
71   {R_16C_REG20_C,   BFD_RELOC_16C_REG20_C},
72   {R_16C_ABS20,     BFD_RELOC_16C_ABS20},
73   {R_16C_ABS20_C,   BFD_RELOC_16C_ABS20_C},
74   {R_16C_ABS24,     BFD_RELOC_16C_ABS24},
75   {R_16C_ABS24_C,   BFD_RELOC_16C_ABS24_C},
76   {R_16C_IMM04,     BFD_RELOC_16C_IMM04},
77   {R_16C_IMM04_C,   BFD_RELOC_16C_IMM04_C},
78   {R_16C_IMM16,     BFD_RELOC_16C_IMM16},
79   {R_16C_IMM16_C,   BFD_RELOC_16C_IMM16_C},
80   {R_16C_IMM20,     BFD_RELOC_16C_IMM20},
81   {R_16C_IMM20_C,   BFD_RELOC_16C_IMM20_C},
82   {R_16C_IMM24,     BFD_RELOC_16C_IMM24},
83   {R_16C_IMM24_C,   BFD_RELOC_16C_IMM24_C},
84   {R_16C_IMM32,     BFD_RELOC_16C_IMM32},
85   {R_16C_IMM32_C,   BFD_RELOC_16C_IMM32_C}
86 };
87
88 static reloc_howto_type elf_howto_table[] =
89 {
90   /* 00 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08),
91   /* 01 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08_C),
92   /* 02 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16),
93   /* 03 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16_C),
94   /* 04 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32),
95   /* 05 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32_C),
96   /* 06 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04),
97   /* 07 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04_C),
98   /* 08 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08),
99   /* 09 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08_C),
100   /* 10 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16),
101   /* 11 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16_C),
102   /* 12 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24),
103   /* 13 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24_C),
104   /* 14 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a),
105   /* 15 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a_C),
106   /* 16 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04),
107   /* 17 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04_C),
108   /* 18 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a),
109   /* 19 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a_C),
110   /* 20 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14),
111   /* 21 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14_C),
112   /* 22 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16),
113   /* 23 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16_C),
114   /* 24 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20),
115   /* 25 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20_C),
116   /* 26 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20),
117   /* 27 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20_C),
118   /* 28 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24),
119   /* 29 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24_C),
120   /* 30 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04),
121   /* 31 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04_C),
122   /* 32 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16),
123   /* 33 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16_C),
124   /* 34 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20),
125   /* 35 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20_C),
126   /* 36 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24),
127   /* 37 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24_C),
128   /* 38 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32),
129   /* 39 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32_C)
130 };
131
132
133 /* Code to turn a code_type into a howto ptr, uses the above howto table.  */
134
135 static reloc_howto_type *
136 elf_cr16c_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
137                              bfd_reloc_code_real_type code)
138 {
139   unsigned int i;
140
141   for (i = 0; i < RINDEX_16C_MAX; i++)
142     {
143       if (code == reloc_map_index[i].bfd_reloc_enum)
144         {
145           /* printf ("CR16C Relocation Type is - %x\n", code); */
146           return & elf_howto_table[i];
147         }
148     }
149
150   /* printf ("This relocation Type is not supported - %x\n", code); */
151   return 0;
152 }
153
154 static reloc_howto_type *
155 elf_cr16c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
156                              const char *r_name)
157 {
158   unsigned int i;
159
160   for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
161     if (elf_howto_table[i].name != NULL
162         && strcasecmp (elf_howto_table[i].name, r_name) == 0)
163       return &elf_howto_table[i];
164
165   return NULL;
166 }
167
168 static void
169 elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
170                          arelent *cache_ptr ATTRIBUTE_UNUSED,
171                          Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
172 {
173   abort ();
174 }
175
176 static void
177 elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
178                              arelent *cache_ptr,
179                              Elf_Internal_Rela *dst)
180 {
181   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
182
183   if (r_type >= RINDEX_16C_MAX)
184     {
185       /* xgettext:c-format */
186       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
187                           abfd, r_type);
188       r_type = 0;
189     }
190   cache_ptr->howto = &elf_howto_table[r_type];
191 }
192
193 /* Perform a relocation as part of a final link.  */
194
195 static bfd_reloc_status_type
196 cr16c_elf_final_link_relocate (reloc_howto_type *howto,
197                                bfd *abfd,
198                                bfd *output_bfd ATTRIBUTE_UNUSED,
199                                asection *input_section,
200                                bfd_byte *data,
201                                bfd_vma octets,
202                                bfd_vma Rvalue,
203                                bfd_vma addend ATTRIBUTE_UNUSED,
204                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
205                                asection *sym_sec ATTRIBUTE_UNUSED,
206                                int is_local ATTRIBUTE_UNUSED)
207 {
208   long value;
209   short sword;                  /* Extracted from the hole and put back.  */
210   unsigned long format, addr_type, code_factor;
211   unsigned short size;
212   unsigned short r_type;
213
214   unsigned long disp20_opcod;
215   char neg = 0;
216   char neg2pos = 0;
217
218   long left_val = 0;
219   long plus_factor = 0;         /* To be added to the hole.  */
220
221 #define MIN_BYTE        ((int) 0xFFFFFF80)
222 #define MIN_WORD        ((int) 0xFFFF8000)
223 #define MAX_UWORD       ((unsigned) 0x0000FFFF)
224 #define MAX_UBYTE       ((unsigned) 0x000000FF)
225
226   r_type = reloc_map_index[howto->type].cr_reloc_type;
227   format = r_type & R_FORMAT;
228   size = r_type & R_SIZESP;
229   addr_type = r_type & R_ADDRTYPE;
230   code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
231
232   switch (format)
233     {
234     case R_NUMBER:
235       switch (size)
236         {
237         case R_S_16C_08:        /* One byte.  */
238           value = bfd_get_8 (abfd, (char *) data + octets);
239           break;
240         case R_S_16C_16:        /* Two bytes. */
241           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
242           value = sword;
243           break;
244         case R_S_16C_32:        /* Four bytes.  */
245           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
246           break;
247         default:
248           return bfd_reloc_notsupported;
249         }
250       break;
251
252     case R_16C_DISPL:
253       switch (size)
254         {
255         case R_S_16C_04:    /* word1(4-7).  */
256           value = bfd_get_8 (abfd, (char *) data + octets);
257           left_val = value & 0xF;
258           value = (value & 0xF0) >> 4;
259           value++;
260           value <<= 1;
261           break;
262         case R_S_16C_08:    /* word1(0-3,8-11).  */
263           sword = bfd_get_16 (abfd, (char *) data + octets);
264           value = sword & 0x000F;
265           value |= ((sword & 0x0F00) >> 4);
266           left_val = sword & 0xF0F0;
267           value <<= 1;
268           if (value & 0x100)
269             value |= 0xFFFFFF00;
270           break;
271         case R_S_16C_16:    /* word2.  */
272           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
273           value = sword;
274           value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15);
275           value <<= 1;
276           if (value & 0x10000)
277             value |= 0xFFFF0000;
278           break;
279         case R_S_16C_24_a:      /* word1(0-7),word2.  */
280           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
281           left_val = value & 0x0000FF00;
282           value = ((value & 0xFFFE0000) >> 17) |
283             ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15);
284           value <<= 1;
285           if (value & 0x1000000)
286             value |= 0xFE000000;
287           break;
288         case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
289           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
290           left_val = value & 0x0000F0F0;
291           value = ((value >> 16) & 0x0000FFFF) |
292             ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
293
294           value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23);
295
296           value <<= 1;
297           if (value & 0x1000000)
298             value |= 0xFE000000;
299           break;
300         default:
301           return bfd_reloc_notsupported;
302         }
303       break;
304
305     case R_16C_REGREL:
306       switch (size)
307         {
308         case R_S_16C_04:    /* word1(12-15) not scaled.  */
309           value = bfd_get_8 (abfd, (char *) data + octets);
310           left_val = value & 0xF0;
311           value = value & 0xF;
312           break;
313         case R_S_16C_04_a:      /* word1(12-15) scaled by 2.  */
314           value = bfd_get_8 (abfd, (char *) data + octets);
315           left_val = value & 0xF0;
316           value = value & 0xF;
317           value <<= 1;
318           break;
319         case R_S_16C_14:    /* word1(4-5),word2(0-3,8-15).  */
320           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
321           left_val = value & 0x00F0FFCF;
322           value = ((value & 0xc0000000) >> 24) |
323             ((value & 0x3F000000) >> 16) |
324             ((value & 0x000F0000) >> 16) | (value & 0x00000030);
325           break;
326         case R_S_16C_16:    /* word2.  */
327           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
328           value = sword;
329           break;
330         case R_S_16C_20:    /* word2(8-11),word3.  */
331           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
332           left_val = value & 0xF0;
333           value = (value & 0xF) << 16;
334           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1);
335           value = value | (unsigned short) sword;
336           disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3);
337           disp20_opcod |= 0x0FFF0000;
338           if ((disp20_opcod == 0x4FFF0018) ||   /* loadb -disp20(reg) */
339               (disp20_opcod == 0x5FFF0018) ||   /* loadb -disp20(rp)  */
340               (disp20_opcod == 0x8FFF0018) ||   /* loadd -disp20(reg) */
341               (disp20_opcod == 0x9FFF0018) ||   /* loadd -disp20(rp)  */
342               (disp20_opcod == 0xCFFF0018) ||   /* loadw -disp20(reg) */
343               (disp20_opcod == 0xDFFF0018) ||   /* loadw -disp20(rp)  */
344               (disp20_opcod == 0x4FFF0019) ||   /* storb -disp20(reg) */
345               (disp20_opcod == 0x5FFF0019) ||   /* storb -disp20(rp)  */
346               (disp20_opcod == 0x8FFF0019) ||   /* stord -disp20(reg) */
347               (disp20_opcod == 0x9FFF0019) ||   /* stord -disp20(rp)  */
348               (disp20_opcod == 0xCFFF0019) ||   /* storw -disp20(reg) */
349               (disp20_opcod == 0xDFFF0019))
350             {   /* storw -disp20(rp).  */
351               neg = 1;
352               value |= 0xFFF00000;
353             }
354
355           break;
356         default:
357           return bfd_reloc_notsupported;
358         }
359       break;
360
361     case R_16C_ABS:
362       switch (size)
363         {
364         case R_S_16C_20:    /* word1(0-3),word2.  */
365           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
366           left_val = value & 0x0000FFF0;
367           value = ((value & 0xFFFF0000) >> 16) |
368             ((value & 0x0000000F) << 16);
369           break;
370         case R_S_16C_24:   /* word2(0-3,8-11),word3.  */
371           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
372           left_val = value & 0x0000F0F0;
373           value = ((value & 0xFFFF0000) >> 16) |
374             ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
375           break;
376         default:
377           return bfd_reloc_notsupported;
378         }
379       break;
380
381     case R_16C_IMMED:
382       switch (size)
383         {
384         case R_S_16C_04:    /* word1/2(4-7).  */
385           value = bfd_get_8 (abfd, (char *) data + octets);
386           left_val = value & 0xF;
387           value = (value & 0xF0) >> 4;
388           break;
389         case R_S_16C_16:    /* word2.  */
390           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
391           value = sword;
392           break;
393         case R_S_16C_20:    /* word1(0-3),word2.  */
394           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
395           left_val = value & 0x0000FFF0;
396           value = ((value & 0xFFFF0000) >> 16) |
397             ((value & 0x0000000F) << 16);
398           break;
399         case R_S_16C_32:    /* word2, word3.  */
400           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
401           value = ((value & 0x0000FFFF) << 16) |
402             ((value & 0xFFFF0000) >> 16);
403           break;
404         default:
405           return bfd_reloc_notsupported;
406         }
407       break;
408     default:
409       return bfd_reloc_notsupported;
410     }
411
412   switch ((r_type & R_RELTO) >> 4)
413     {
414
415     case 0:     /* R_ABS.  */
416       plus_factor = Rvalue;
417       break;
418     case 1:     /* R_PCREL.  */
419       plus_factor = Rvalue -
420         (input_section->output_section->vma + input_section->output_offset);
421       break;
422     default:
423       return bfd_reloc_notsupported;
424     }
425
426   if (neg)
427     {
428       if (plus_factor >= -value)
429         neg2pos = 1;
430       /* We need to change load/stor with negative
431          displ opcode to positive disp opcode (CR16C).  */
432     }
433
434   value = value + (plus_factor >> code_factor);
435
436   switch (format)
437     {
438     case R_NUMBER:
439       switch (size)
440         {
441         case R_S_16C_08:        /* One byte.  */
442           if (value > (int) MAX_UBYTE || value < MIN_BYTE)
443             return bfd_reloc_overflow;
444           value &= 0xFF;
445           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
446           break;
447
448         case R_S_16C_16:        /* Two bytes.  */
449           if (value > (int) MAX_UWORD || value < MIN_WORD)
450             return bfd_reloc_overflow;
451           value &= 0xFFFF;
452           sword = value;
453           bfd_put_16 (abfd, (bfd_vma) sword,
454                       (unsigned char *) data + octets);
455           break;
456
457         case R_S_16C_32:        /* Four bytes.  */
458           value &= 0xFFFFFFFF;
459           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
460           break;
461
462         default:
463           return bfd_reloc_notsupported;
464         }
465       break;
466
467     case R_16C_DISPL:
468       switch (size)
469         {
470         case R_S_16C_04:        /* word1(4-7).  */
471           if ((value - 32) > 32 || value < 2)
472             return bfd_reloc_overflow;
473           value >>= 1;
474           value--;
475           value &= 0xF;
476           value <<= 4;
477           value |= left_val;
478           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
479           break;
480
481         case R_S_16C_08:    /* word1(0-3,8-11).  */
482           if (value > 255 || value < -256 || value == 0x80)
483             return bfd_reloc_overflow;
484           value &= 0x1FF;
485           value >>= 1;
486           sword = value & 0x000F;
487           sword |= (value & 0x00F0) << 4;
488           sword |= left_val;
489           bfd_put_16 (abfd, (bfd_vma) sword,
490                       (unsigned char *) data + octets);
491           break;
492
493         case R_S_16C_16:    /* word2.  */
494           if (value > 65535 || value < -65536)
495             return bfd_reloc_overflow;
496           value >>= 1;
497           value &= 0xFFFF;
498           value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1);
499           sword = value;
500           bfd_put_16 (abfd, (bfd_vma) sword,
501                       (unsigned char *) data + octets);
502           break;
503
504         case R_S_16C_24_a:      /* word1(0-7),word2.  */
505           if (value > 16777215 || value < -16777216)
506             return bfd_reloc_overflow;
507           value &= 0x1FFFFFF;
508           value >>= 1;
509           value = ((value & 0x00007FFF) << 17) |
510             ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15);
511           value |= left_val;
512           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
513           break;
514
515         case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
516           if (value > 16777215 || value < -16777216)
517             return bfd_reloc_overflow;
518           value &= 0x1FFFFFF;
519           value >>= 1;
520
521           value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23);
522
523           value = ((value & 0x0000FFFF) << 16) |
524             ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
525           value |= left_val;
526           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
527           break;
528
529         default:
530           return bfd_reloc_notsupported;
531         }
532       break;
533
534     case R_16C_REGREL:
535       switch (size)
536         {
537         case R_S_16C_04:        /* word1(12-15) not scaled.  */
538           if (value > 13 || value < 0)
539             return bfd_reloc_overflow;
540           value &= 0xF;
541           value |= left_val;
542           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
543           break;
544
545         case R_S_16C_04_a:      /* word1(12-15) not scaled.  */
546           if (value > 26 || value < 0)
547             return bfd_reloc_overflow;
548           value &= 0x1F;
549           value >>= 1;
550           value |= left_val;
551           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
552           break;
553
554         case R_S_16C_14:        /* word1(4-5),word2(0-3,8-15).  */
555           if (value < 0 || value > 16383)
556             return bfd_reloc_overflow;
557           value &= 0x3FFF;
558           value = ((value & 0x000000c0) << 24) |
559             ((value & 0x00003F00) << 16) |
560             ((value & 0x0000000F) << 16) | (value & 0x00000030);
561           value |= left_val;
562           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
563           break;
564
565         case R_S_16C_16:        /* word2.  */
566           if (value > 65535 || value < 0)
567             return bfd_reloc_overflow;
568           value &= 0xFFFF;
569           sword = value;
570           bfd_put_16 (abfd, (bfd_vma) sword,
571                       (unsigned char *) data + octets);
572           break;
573
574         case R_S_16C_20:        /* word2(8-11),word3.  */
575           /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */
576           value &= 0xFFFFF;
577           sword = value & 0x0000FFFF;
578           value = (value & 0x000F0000) >> 16;
579           value |= left_val;
580           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
581           bfd_put_16 (abfd, (bfd_vma) sword,
582                       (unsigned char *) data + octets + 1);
583           if (neg2pos)
584             {
585               /* Change load/stor negative displ opcode
586                  to load/stor positive displ opcode.  */
587               value = bfd_get_8 (abfd, (char *) data + octets - 3);
588               value &= 0xF7;
589               value |= 0x2;
590               bfd_put_8 (abfd, (bfd_vma) value,
591                          (unsigned char *) data + octets - 3);
592             }
593           break;
594
595         default:
596           return bfd_reloc_notsupported;
597         }
598       break;
599
600     case R_16C_ABS:
601       switch (size)
602         {
603         case R_S_16C_20:        /* word1(0-3),word2.  */
604           if (value > 1048575 || value < 0)
605             return bfd_reloc_overflow;
606           value &= 0xFFFFF;
607           value = ((value & 0x0000FFFF) << 16) |
608             ((value & 0x000F0000) >> 16);
609           value |= left_val;
610           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
611           break;
612
613         case R_S_16C_24:        /* word2(0-3,8-11),word3.  */
614           /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */
615           value &= 0xFFFFFF;
616           value = ((value & 0x0000FFFF) << 16) |
617             ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
618           value |= left_val;
619           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
620           break;
621
622         default:
623           return bfd_reloc_notsupported;
624         }
625       break;
626
627     case R_16C_IMMED:
628       switch (size)
629         {
630         case R_S_16C_04:        /* word1/2(4-7).  */
631           if (value > 15 || value < -1)
632             return bfd_reloc_overflow;
633           value &= 0xF;
634           value <<= 4;
635           value |= left_val;
636           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
637           break;
638
639         case R_S_16C_16:        /* word2.  */
640           if (value > 32767 || value < -32768)
641             return bfd_reloc_overflow;
642           value &= 0xFFFF;
643           sword = value;
644           bfd_put_16 (abfd, (bfd_vma) sword,
645                       (unsigned char *) data + octets);
646           break;
647
648         case R_S_16C_20:        /* word1(0-3),word2.  */
649           if (value > 1048575 || value < 0)
650             return bfd_reloc_overflow;
651           value &= 0xFFFFF;
652           value = ((value & 0x0000FFFF) << 16) |
653             ((value & 0x000F0000) >> 16);
654           value |= left_val;
655           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
656           break;
657
658         case R_S_16C_32:        /* word2, word3.  */
659           value &= 0xFFFFFFFF;
660           value = ((value & 0x0000FFFF) << 16) |
661             ((value & 0xFFFF0000) >> 16);
662           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
663           break;
664
665         default:
666           return bfd_reloc_notsupported;
667         }
668       break;
669     default:
670       return bfd_reloc_notsupported;
671     }
672
673   return bfd_reloc_ok;
674 }
675
676 /* Relocate a CR16C ELF section.  */
677
678 static bfd_boolean
679 elf32_cr16c_relocate_section (bfd *output_bfd,
680                               struct bfd_link_info *info,
681                               bfd *input_bfd,
682                               asection *input_section,
683                               bfd_byte *contents,
684                               Elf_Internal_Rela *relocs,
685                               Elf_Internal_Sym *local_syms,
686                               asection **local_sections)
687 {
688   Elf_Internal_Shdr *symtab_hdr;
689   struct elf_link_hash_entry **sym_hashes;
690   Elf_Internal_Rela *rel, *relend;
691
692   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
693   sym_hashes = elf_sym_hashes (input_bfd);
694
695   rel = relocs;
696   relend = relocs + input_section->reloc_count;
697   for (; rel < relend; rel++)
698     {
699       int r_type;
700       reloc_howto_type *howto;
701       unsigned long r_symndx;
702       Elf_Internal_Sym *sym;
703       asection *sec;
704       struct elf_link_hash_entry *h;
705       bfd_vma relocation;
706       bfd_reloc_status_type r;
707
708       r_symndx = ELF32_R_SYM (rel->r_info);
709       r_type = ELF32_R_TYPE (rel->r_info);
710       howto = elf_howto_table + r_type;
711
712       h = NULL;
713       sym = NULL;
714       sec = NULL;
715       if (r_symndx < symtab_hdr->sh_info)
716         {
717           sym = local_syms + r_symndx;
718           sec = local_sections[r_symndx];
719           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
720         }
721       else
722         {
723           bfd_boolean unresolved_reloc, warned, ignored;
724
725           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
726                                    r_symndx, symtab_hdr, sym_hashes,
727                                    h, sec, relocation,
728                                    unresolved_reloc, warned, ignored);
729         }
730
731       if (sec != NULL && discarded_section (sec))
732         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
733                                          rel, 1, relend, howto, 0, contents);
734
735       if (bfd_link_relocatable (info))
736         {
737           /* This is a relocatable link.  We don't have to change
738              anything, unless the reloc is against a section symbol,
739              in which case we have to adjust according to where the
740              section symbol winds up in the output section.  */
741           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
742             rel->r_addend += sec->output_offset;
743           continue;
744         }
745
746       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
747                                          input_section,
748                                          contents, rel->r_offset,
749                                          relocation, rel->r_addend,
750                                          info, sec, h == NULL);
751
752       if (r != bfd_reloc_ok)
753         {
754           const char *name;
755           const char *msg = (const char *) 0;
756
757           if (h != NULL)
758             name = h->root.root.string;
759           else
760             {
761               name = (bfd_elf_string_from_elf_section
762                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
763               if (name == NULL || *name == '\0')
764                 name = bfd_section_name (input_bfd, sec);
765             }
766
767           switch (r)
768             {
769             case bfd_reloc_overflow:
770               (*info->callbacks->reloc_overflow)
771                 (info, (h ? &h->root : NULL), name, howto->name,
772                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
773               break;
774
775             case bfd_reloc_undefined:
776               (*info->callbacks->undefined_symbol)
777                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
778               break;
779
780             case bfd_reloc_outofrange:
781               msg = _("internal error: out of range error");
782               goto common_error;
783
784             case bfd_reloc_notsupported:
785               msg = _("internal error: unsupported relocation error");
786               goto common_error;
787
788             case bfd_reloc_dangerous:
789               msg = _("internal error: dangerous error");
790               goto common_error;
791
792             default:
793               msg = _("internal error: unknown error");
794               /* fall through */
795
796             common_error:
797               (*info->callbacks->warning) (info, msg, name, input_bfd,
798                                            input_section, rel->r_offset);
799               break;
800             }
801         }
802     }
803
804   return TRUE;
805 }
806
807 /* CR16C ELF uses three common sections:
808    One is for default common symbols (placed in usual common section).
809    Second is for near common symbols (placed in "ncommon" section).
810    Third is for far common symbols (placed in "fcommon" section).
811    The following implementation is based on elf32-mips architecture */
812
813 static asection  cr16c_elf_fcom_section;
814 static asymbol   cr16c_elf_fcom_symbol;
815 static asymbol * cr16c_elf_fcom_symbol_ptr;
816 static asection  cr16c_elf_ncom_section;
817 static asymbol   cr16c_elf_ncom_symbol;
818 static asymbol * cr16c_elf_ncom_symbol_ptr;
819
820 /* Given a BFD section, try to locate the
821    corresponding ELF section index.  */
822
823 static bfd_boolean
824 elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
825                                       asection *sec,
826                                       int *retval)
827 {
828   if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
829     *retval = SHN_CR16C_FCOMMON;
830   else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
831     *retval = SHN_CR16C_NCOMMON;
832   else
833     return FALSE;
834
835   return TRUE;
836 }
837
838 /* Handle the special CR16C section numbers that a symbol may use.  */
839
840 static void
841 elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
842                                asymbol *asym)
843 {
844   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
845   unsigned int indx;
846
847   indx = elfsym->internal_elf_sym.st_shndx;
848
849   switch (indx)
850     {
851     case SHN_CR16C_FCOMMON:
852       if (cr16c_elf_fcom_section.name == NULL)
853         {
854           /* Initialize the far common section.  */
855           cr16c_elf_fcom_section.name = ".fcommon";
856           cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
857           cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
858           cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
859           cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
860           cr16c_elf_fcom_symbol.name = ".fcommon";
861           cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
862           cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
863           cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
864         }
865       asym->section = &cr16c_elf_fcom_section;
866       asym->value = elfsym->internal_elf_sym.st_size;
867       break;
868     case SHN_CR16C_NCOMMON:
869       if (cr16c_elf_ncom_section.name == NULL)
870         {
871           /* Initialize the far common section.  */
872           cr16c_elf_ncom_section.name = ".ncommon";
873           cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
874           cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
875           cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
876           cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
877           cr16c_elf_ncom_symbol.name = ".ncommon";
878           cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
879           cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
880           cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
881         }
882       asym->section = &cr16c_elf_ncom_section;
883       asym->value = elfsym->internal_elf_sym.st_size;
884       break;
885     }
886 }
887
888 /* Hook called by the linker routine which adds symbols from an object
889    file.  We must handle the special cr16c section numbers here.  */
890
891 static bfd_boolean
892 elf32_cr16c_add_symbol_hook (bfd *abfd,
893                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
894                              Elf_Internal_Sym *sym,
895                              const char **namep ATTRIBUTE_UNUSED,
896                              flagword *flagsp ATTRIBUTE_UNUSED,
897                              asection **secp,
898                              bfd_vma *valp)
899 {
900   unsigned int indx = sym->st_shndx;
901
902   switch (indx)
903     {
904     case SHN_CR16C_FCOMMON:
905       *secp = bfd_make_section_old_way (abfd, ".fcommon");
906       (*secp)->flags |= SEC_IS_COMMON;
907       *valp = sym->st_size;
908       break;
909     case SHN_CR16C_NCOMMON:
910       *secp = bfd_make_section_old_way (abfd, ".ncommon");
911       (*secp)->flags |= SEC_IS_COMMON;
912       *valp = sym->st_size;
913       break;
914     }
915
916   return TRUE;
917 }
918
919 static int
920 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
921                                      const char *name ATTRIBUTE_UNUSED,
922                                      Elf_Internal_Sym *sym,
923                                      asection *input_sec,
924                                      struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
925 {
926   /* If we see a common symbol, which implies a relocatable link, then
927      if a symbol was in a special common section in an input file, mark
928      it as a special common in the output file.  */
929
930   if (sym->st_shndx == SHN_COMMON)
931     {
932       if (strcmp (input_sec->name, ".fcommon") == 0)
933         sym->st_shndx = SHN_CR16C_FCOMMON;
934       else if (strcmp (input_sec->name, ".ncommon") == 0)
935         sym->st_shndx = SHN_CR16C_NCOMMON;
936     }
937
938   return 1;
939 }
940
941 /* Definitions for setting CR16C target vector.  */
942 #define TARGET_LITTLE_SYM               cr16c_elf32_vec
943 #define TARGET_LITTLE_NAME              "elf32-cr16c"
944 #define ELF_ARCH                        bfd_arch_cr16c
945 #define ELF_MACHINE_CODE                EM_CR
946 #define ELF_MAXPAGESIZE                 0x1
947 #define elf_symbol_leading_char         '_'
948
949 #define bfd_elf32_bfd_reloc_type_lookup         elf_cr16c_reloc_type_lookup
950 #define bfd_elf32_bfd_reloc_name_lookup elf_cr16c_reloc_name_lookup
951 #define elf_info_to_howto                       elf_cr16c_info_to_howto
952 #define elf_info_to_howto_rel                   elf_cr16c_info_to_howto_rel
953 #define elf_backend_relocate_section            elf32_cr16c_relocate_section
954 #define elf_backend_symbol_processing           elf32_cr16c_symbol_processing
955 #define elf_backend_section_from_bfd_section    elf32_cr16c_section_from_bfd_section
956 #define elf_backend_add_symbol_hook             elf32_cr16c_add_symbol_hook
957 #define elf_backend_link_output_symbol_hook     elf32_cr16c_link_output_symbol_hook
958
959 #define elf_backend_can_gc_sections     1
960
961 #include "elf32-target.h"