packaging: Enable testing infrastructure
[external/binutils.git] / bfd / elf32-cr16c.c
1 /* BFD back-end for National Semiconductor's CR16C ELF
2    Copyright (C) 2004-2019 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 bfd_boolean
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   return FALSE;
174 }
175
176 static bfd_boolean
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       bfd_set_error (bfd_error_bad_value);
189       return FALSE;
190     }
191   cache_ptr->howto = &elf_howto_table[r_type];
192   return TRUE;
193 }
194
195 /* Perform a relocation as part of a final link.  */
196
197 static bfd_reloc_status_type
198 cr16c_elf_final_link_relocate (reloc_howto_type *howto,
199                                bfd *abfd,
200                                bfd *output_bfd ATTRIBUTE_UNUSED,
201                                asection *input_section,
202                                bfd_byte *data,
203                                bfd_vma octets,
204                                bfd_vma Rvalue,
205                                bfd_vma addend ATTRIBUTE_UNUSED,
206                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
207                                asection *sym_sec ATTRIBUTE_UNUSED,
208                                int is_local ATTRIBUTE_UNUSED)
209 {
210   long value;
211   short sword;                  /* Extracted from the hole and put back.  */
212   unsigned long format, addr_type, code_factor;
213   unsigned short size;
214   unsigned short r_type;
215
216   unsigned long disp20_opcod;
217   char neg = 0;
218   char neg2pos = 0;
219
220   long left_val = 0;
221   long plus_factor = 0;         /* To be added to the hole.  */
222
223 #define MIN_BYTE        ((int) 0xFFFFFF80)
224 #define MIN_WORD        ((int) 0xFFFF8000)
225 #define MAX_UWORD       ((unsigned) 0x0000FFFF)
226 #define MAX_UBYTE       ((unsigned) 0x000000FF)
227
228   r_type = reloc_map_index[howto->type].cr_reloc_type;
229   format = r_type & R_FORMAT;
230   size = r_type & R_SIZESP;
231   addr_type = r_type & R_ADDRTYPE;
232   code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
233
234   switch (format)
235     {
236     case R_NUMBER:
237       switch (size)
238         {
239         case R_S_16C_08:        /* One byte.  */
240           value = bfd_get_8 (abfd, (char *) data + octets);
241           break;
242         case R_S_16C_16:        /* Two bytes. */
243           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
244           value = sword;
245           break;
246         case R_S_16C_32:        /* Four bytes.  */
247           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
248           break;
249         default:
250           return bfd_reloc_notsupported;
251         }
252       break;
253
254     case R_16C_DISPL:
255       switch (size)
256         {
257         case R_S_16C_04:    /* word1(4-7).  */
258           value = bfd_get_8 (abfd, (char *) data + octets);
259           left_val = value & 0xF;
260           value = (value & 0xF0) >> 4;
261           value++;
262           value <<= 1;
263           break;
264         case R_S_16C_08:    /* word1(0-3,8-11).  */
265           sword = bfd_get_16 (abfd, (char *) data + octets);
266           value = sword & 0x000F;
267           value |= ((sword & 0x0F00) >> 4);
268           left_val = sword & 0xF0F0;
269           value <<= 1;
270           if (value & 0x100)
271             value |= 0xFFFFFF00;
272           break;
273         case R_S_16C_16:    /* word2.  */
274           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
275           value = sword;
276           value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15);
277           value <<= 1;
278           if (value & 0x10000)
279             value |= 0xFFFF0000;
280           break;
281         case R_S_16C_24_a:      /* word1(0-7),word2.  */
282           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
283           left_val = value & 0x0000FF00;
284           value = ((value & 0xFFFE0000) >> 17) |
285             ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15);
286           value <<= 1;
287           if (value & 0x1000000)
288             value |= 0xFE000000;
289           break;
290         case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
291           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
292           left_val = value & 0x0000F0F0;
293           value = ((value >> 16) & 0x0000FFFF) |
294             ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
295
296           value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23);
297
298           value <<= 1;
299           if (value & 0x1000000)
300             value |= 0xFE000000;
301           break;
302         default:
303           return bfd_reloc_notsupported;
304         }
305       break;
306
307     case R_16C_REGREL:
308       switch (size)
309         {
310         case R_S_16C_04:    /* word1(12-15) not scaled.  */
311           value = bfd_get_8 (abfd, (char *) data + octets);
312           left_val = value & 0xF0;
313           value = value & 0xF;
314           break;
315         case R_S_16C_04_a:      /* word1(12-15) scaled by 2.  */
316           value = bfd_get_8 (abfd, (char *) data + octets);
317           left_val = value & 0xF0;
318           value = value & 0xF;
319           value <<= 1;
320           break;
321         case R_S_16C_14:    /* word1(4-5),word2(0-3,8-15).  */
322           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
323           left_val = value & 0x00F0FFCF;
324           value = ((value & 0xc0000000) >> 24) |
325             ((value & 0x3F000000) >> 16) |
326             ((value & 0x000F0000) >> 16) | (value & 0x00000030);
327           break;
328         case R_S_16C_16:    /* word2.  */
329           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
330           value = sword;
331           break;
332         case R_S_16C_20:    /* word2(8-11),word3.  */
333           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
334           left_val = value & 0xF0;
335           value = (value & 0xF) << 16;
336           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1);
337           value = value | (unsigned short) sword;
338           disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3);
339           disp20_opcod |= 0x0FFF0000;
340           if ((disp20_opcod == 0x4FFF0018) ||   /* loadb -disp20(reg) */
341               (disp20_opcod == 0x5FFF0018) ||   /* loadb -disp20(rp)  */
342               (disp20_opcod == 0x8FFF0018) ||   /* loadd -disp20(reg) */
343               (disp20_opcod == 0x9FFF0018) ||   /* loadd -disp20(rp)  */
344               (disp20_opcod == 0xCFFF0018) ||   /* loadw -disp20(reg) */
345               (disp20_opcod == 0xDFFF0018) ||   /* loadw -disp20(rp)  */
346               (disp20_opcod == 0x4FFF0019) ||   /* storb -disp20(reg) */
347               (disp20_opcod == 0x5FFF0019) ||   /* storb -disp20(rp)  */
348               (disp20_opcod == 0x8FFF0019) ||   /* stord -disp20(reg) */
349               (disp20_opcod == 0x9FFF0019) ||   /* stord -disp20(rp)  */
350               (disp20_opcod == 0xCFFF0019) ||   /* storw -disp20(reg) */
351               (disp20_opcod == 0xDFFF0019))
352             {   /* storw -disp20(rp).  */
353               neg = 1;
354               value |= 0xFFF00000;
355             }
356
357           break;
358         default:
359           return bfd_reloc_notsupported;
360         }
361       break;
362
363     case R_16C_ABS:
364       switch (size)
365         {
366         case R_S_16C_20:    /* word1(0-3),word2.  */
367           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
368           left_val = value & 0x0000FFF0;
369           value = ((value & 0xFFFF0000) >> 16) |
370             ((value & 0x0000000F) << 16);
371           break;
372         case R_S_16C_24:   /* word2(0-3,8-11),word3.  */
373           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
374           left_val = value & 0x0000F0F0;
375           value = ((value & 0xFFFF0000) >> 16) |
376             ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
377           break;
378         default:
379           return bfd_reloc_notsupported;
380         }
381       break;
382
383     case R_16C_IMMED:
384       switch (size)
385         {
386         case R_S_16C_04:    /* word1/2(4-7).  */
387           value = bfd_get_8 (abfd, (char *) data + octets);
388           left_val = value & 0xF;
389           value = (value & 0xF0) >> 4;
390           break;
391         case R_S_16C_16:    /* word2.  */
392           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
393           value = sword;
394           break;
395         case R_S_16C_20:    /* word1(0-3),word2.  */
396           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
397           left_val = value & 0x0000FFF0;
398           value = ((value & 0xFFFF0000) >> 16) |
399             ((value & 0x0000000F) << 16);
400           break;
401         case R_S_16C_32:    /* word2, word3.  */
402           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
403           value = ((value & 0x0000FFFF) << 16) |
404             ((value & 0xFFFF0000) >> 16);
405           break;
406         default:
407           return bfd_reloc_notsupported;
408         }
409       break;
410     default:
411       return bfd_reloc_notsupported;
412     }
413
414   switch ((r_type & R_RELTO) >> 4)
415     {
416
417     case 0:     /* R_ABS.  */
418       plus_factor = Rvalue;
419       break;
420     case 1:     /* R_PCREL.  */
421       plus_factor = Rvalue -
422         (input_section->output_section->vma + input_section->output_offset);
423       break;
424     default:
425       return bfd_reloc_notsupported;
426     }
427
428   if (neg)
429     {
430       if (plus_factor >= -value)
431         neg2pos = 1;
432       /* We need to change load/stor with negative
433          displ opcode to positive disp opcode (CR16C).  */
434     }
435
436   value = value + (plus_factor >> code_factor);
437
438   switch (format)
439     {
440     case R_NUMBER:
441       switch (size)
442         {
443         case R_S_16C_08:        /* One byte.  */
444           if (value > (int) MAX_UBYTE || value < MIN_BYTE)
445             return bfd_reloc_overflow;
446           value &= 0xFF;
447           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
448           break;
449
450         case R_S_16C_16:        /* Two bytes.  */
451           if (value > (int) MAX_UWORD || value < MIN_WORD)
452             return bfd_reloc_overflow;
453           value &= 0xFFFF;
454           sword = value;
455           bfd_put_16 (abfd, (bfd_vma) sword,
456                       (unsigned char *) data + octets);
457           break;
458
459         case R_S_16C_32:        /* Four bytes.  */
460           value &= 0xFFFFFFFF;
461           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
462           break;
463
464         default:
465           return bfd_reloc_notsupported;
466         }
467       break;
468
469     case R_16C_DISPL:
470       switch (size)
471         {
472         case R_S_16C_04:        /* word1(4-7).  */
473           if ((value - 32) > 32 || value < 2)
474             return bfd_reloc_overflow;
475           value >>= 1;
476           value--;
477           value &= 0xF;
478           value <<= 4;
479           value |= left_val;
480           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
481           break;
482
483         case R_S_16C_08:    /* word1(0-3,8-11).  */
484           if (value > 255 || value < -256 || value == 0x80)
485             return bfd_reloc_overflow;
486           value &= 0x1FF;
487           value >>= 1;
488           sword = value & 0x000F;
489           sword |= (value & 0x00F0) << 4;
490           sword |= left_val;
491           bfd_put_16 (abfd, (bfd_vma) sword,
492                       (unsigned char *) data + octets);
493           break;
494
495         case R_S_16C_16:    /* word2.  */
496           if (value > 65535 || value < -65536)
497             return bfd_reloc_overflow;
498           value >>= 1;
499           value &= 0xFFFF;
500           value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1);
501           sword = value;
502           bfd_put_16 (abfd, (bfd_vma) sword,
503                       (unsigned char *) data + octets);
504           break;
505
506         case R_S_16C_24_a:      /* word1(0-7),word2.  */
507           if (value > 16777215 || value < -16777216)
508             return bfd_reloc_overflow;
509           value &= 0x1FFFFFF;
510           value >>= 1;
511           value = ((value & 0x00007FFF) << 17) |
512             ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15);
513           value |= left_val;
514           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
515           break;
516
517         case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
518           if (value > 16777215 || value < -16777216)
519             return bfd_reloc_overflow;
520           value &= 0x1FFFFFF;
521           value >>= 1;
522
523           value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23);
524
525           value = ((value & 0x0000FFFF) << 16) |
526             ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
527           value |= left_val;
528           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
529           break;
530
531         default:
532           return bfd_reloc_notsupported;
533         }
534       break;
535
536     case R_16C_REGREL:
537       switch (size)
538         {
539         case R_S_16C_04:        /* word1(12-15) not scaled.  */
540           if (value > 13 || value < 0)
541             return bfd_reloc_overflow;
542           value &= 0xF;
543           value |= left_val;
544           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
545           break;
546
547         case R_S_16C_04_a:      /* word1(12-15) not scaled.  */
548           if (value > 26 || value < 0)
549             return bfd_reloc_overflow;
550           value &= 0x1F;
551           value >>= 1;
552           value |= left_val;
553           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
554           break;
555
556         case R_S_16C_14:        /* word1(4-5),word2(0-3,8-15).  */
557           if (value < 0 || value > 16383)
558             return bfd_reloc_overflow;
559           value &= 0x3FFF;
560           value = ((value & 0x000000c0) << 24) |
561             ((value & 0x00003F00) << 16) |
562             ((value & 0x0000000F) << 16) | (value & 0x00000030);
563           value |= left_val;
564           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
565           break;
566
567         case R_S_16C_16:        /* word2.  */
568           if (value > 65535 || value < 0)
569             return bfd_reloc_overflow;
570           value &= 0xFFFF;
571           sword = value;
572           bfd_put_16 (abfd, (bfd_vma) sword,
573                       (unsigned char *) data + octets);
574           break;
575
576         case R_S_16C_20:        /* word2(8-11),word3.  */
577           /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */
578           value &= 0xFFFFF;
579           sword = value & 0x0000FFFF;
580           value = (value & 0x000F0000) >> 16;
581           value |= left_val;
582           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
583           bfd_put_16 (abfd, (bfd_vma) sword,
584                       (unsigned char *) data + octets + 1);
585           if (neg2pos)
586             {
587               /* Change load/stor negative displ opcode
588                  to load/stor positive displ opcode.  */
589               value = bfd_get_8 (abfd, (char *) data + octets - 3);
590               value &= 0xF7;
591               value |= 0x2;
592               bfd_put_8 (abfd, (bfd_vma) value,
593                          (unsigned char *) data + octets - 3);
594             }
595           break;
596
597         default:
598           return bfd_reloc_notsupported;
599         }
600       break;
601
602     case R_16C_ABS:
603       switch (size)
604         {
605         case R_S_16C_20:        /* word1(0-3),word2.  */
606           if (value > 1048575 || value < 0)
607             return bfd_reloc_overflow;
608           value &= 0xFFFFF;
609           value = ((value & 0x0000FFFF) << 16) |
610             ((value & 0x000F0000) >> 16);
611           value |= left_val;
612           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
613           break;
614
615         case R_S_16C_24:        /* word2(0-3,8-11),word3.  */
616           /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */
617           value &= 0xFFFFFF;
618           value = ((value & 0x0000FFFF) << 16) |
619             ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
620           value |= left_val;
621           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
622           break;
623
624         default:
625           return bfd_reloc_notsupported;
626         }
627       break;
628
629     case R_16C_IMMED:
630       switch (size)
631         {
632         case R_S_16C_04:        /* word1/2(4-7).  */
633           if (value > 15 || value < -1)
634             return bfd_reloc_overflow;
635           value &= 0xF;
636           value <<= 4;
637           value |= left_val;
638           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
639           break;
640
641         case R_S_16C_16:        /* word2.  */
642           if (value > 32767 || value < -32768)
643             return bfd_reloc_overflow;
644           value &= 0xFFFF;
645           sword = value;
646           bfd_put_16 (abfd, (bfd_vma) sword,
647                       (unsigned char *) data + octets);
648           break;
649
650         case R_S_16C_20:        /* word1(0-3),word2.  */
651           if (value > 1048575 || value < 0)
652             return bfd_reloc_overflow;
653           value &= 0xFFFFF;
654           value = ((value & 0x0000FFFF) << 16) |
655             ((value & 0x000F0000) >> 16);
656           value |= left_val;
657           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
658           break;
659
660         case R_S_16C_32:        /* word2, word3.  */
661           value &= 0xFFFFFFFF;
662           value = ((value & 0x0000FFFF) << 16) |
663             ((value & 0xFFFF0000) >> 16);
664           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
665           break;
666
667         default:
668           return bfd_reloc_notsupported;
669         }
670       break;
671     default:
672       return bfd_reloc_notsupported;
673     }
674
675   return bfd_reloc_ok;
676 }
677
678 /* Relocate a CR16C ELF section.  */
679
680 static bfd_boolean
681 elf32_cr16c_relocate_section (bfd *output_bfd,
682                               struct bfd_link_info *info,
683                               bfd *input_bfd,
684                               asection *input_section,
685                               bfd_byte *contents,
686                               Elf_Internal_Rela *relocs,
687                               Elf_Internal_Sym *local_syms,
688                               asection **local_sections)
689 {
690   Elf_Internal_Shdr *symtab_hdr;
691   struct elf_link_hash_entry **sym_hashes;
692   Elf_Internal_Rela *rel, *relend;
693
694   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
695   sym_hashes = elf_sym_hashes (input_bfd);
696
697   rel = relocs;
698   relend = relocs + input_section->reloc_count;
699   for (; rel < relend; rel++)
700     {
701       int r_type;
702       reloc_howto_type *howto;
703       unsigned long r_symndx;
704       Elf_Internal_Sym *sym;
705       asection *sec;
706       struct elf_link_hash_entry *h;
707       bfd_vma relocation;
708       bfd_reloc_status_type r;
709
710       r_symndx = ELF32_R_SYM (rel->r_info);
711       r_type = ELF32_R_TYPE (rel->r_info);
712       howto = elf_howto_table + r_type;
713
714       h = NULL;
715       sym = NULL;
716       sec = NULL;
717       if (r_symndx < symtab_hdr->sh_info)
718         {
719           sym = local_syms + r_symndx;
720           sec = local_sections[r_symndx];
721           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
722         }
723       else
724         {
725           bfd_boolean unresolved_reloc, warned, ignored;
726
727           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
728                                    r_symndx, symtab_hdr, sym_hashes,
729                                    h, sec, relocation,
730                                    unresolved_reloc, warned, ignored);
731         }
732
733       if (sec != NULL && discarded_section (sec))
734         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
735                                          rel, 1, relend, howto, 0, contents);
736
737       if (bfd_link_relocatable (info))
738         {
739           /* This is a relocatable link.  We don't have to change
740              anything, unless the reloc is against a section symbol,
741              in which case we have to adjust according to where the
742              section symbol winds up in the output section.  */
743           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
744             rel->r_addend += sec->output_offset;
745           continue;
746         }
747
748       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
749                                          input_section,
750                                          contents, rel->r_offset,
751                                          relocation, rel->r_addend,
752                                          info, sec, h == NULL);
753
754       if (r != bfd_reloc_ok)
755         {
756           const char *name;
757           const char *msg = (const char *) 0;
758
759           if (h != NULL)
760             name = h->root.root.string;
761           else
762             {
763               name = (bfd_elf_string_from_elf_section
764                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
765               if (name == NULL || *name == '\0')
766                 name = bfd_section_name (input_bfd, sec);
767             }
768
769           switch (r)
770             {
771             case bfd_reloc_overflow:
772               (*info->callbacks->reloc_overflow)
773                 (info, (h ? &h->root : NULL), name, howto->name,
774                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
775               break;
776
777             case bfd_reloc_undefined:
778               (*info->callbacks->undefined_symbol)
779                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
780               break;
781
782             case bfd_reloc_outofrange:
783               msg = _("internal error: out of range error");
784               goto common_error;
785
786             case bfd_reloc_notsupported:
787               msg = _("internal error: unsupported relocation error");
788               goto common_error;
789
790             case bfd_reloc_dangerous:
791               msg = _("internal error: dangerous error");
792               goto common_error;
793
794             default:
795               msg = _("internal error: unknown error");
796               /* fall through */
797
798             common_error:
799               (*info->callbacks->warning) (info, msg, name, input_bfd,
800                                            input_section, rel->r_offset);
801               break;
802             }
803         }
804     }
805
806   return TRUE;
807 }
808
809 /* CR16C ELF uses three common sections:
810    One is for default common symbols (placed in usual common section).
811    Second is for near common symbols (placed in "ncommon" section).
812    Third is for far common symbols (placed in "fcommon" section).
813    The following implementation is based on elf32-mips architecture */
814
815 static asection  cr16c_elf_fcom_section;
816 static asymbol   cr16c_elf_fcom_symbol;
817 static asymbol * cr16c_elf_fcom_symbol_ptr;
818 static asection  cr16c_elf_ncom_section;
819 static asymbol   cr16c_elf_ncom_symbol;
820 static asymbol * cr16c_elf_ncom_symbol_ptr;
821
822 /* Given a BFD section, try to locate the
823    corresponding ELF section index.  */
824
825 static bfd_boolean
826 elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
827                                       asection *sec,
828                                       int *retval)
829 {
830   if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
831     *retval = SHN_CR16C_FCOMMON;
832   else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
833     *retval = SHN_CR16C_NCOMMON;
834   else
835     return FALSE;
836
837   return TRUE;
838 }
839
840 /* Handle the special CR16C section numbers that a symbol may use.  */
841
842 static void
843 elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
844                                asymbol *asym)
845 {
846   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
847   unsigned int indx;
848
849   indx = elfsym->internal_elf_sym.st_shndx;
850
851   switch (indx)
852     {
853     case SHN_CR16C_FCOMMON:
854       if (cr16c_elf_fcom_section.name == NULL)
855         {
856           /* Initialize the far common section.  */
857           cr16c_elf_fcom_section.name = ".fcommon";
858           cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
859           cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
860           cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
861           cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
862           cr16c_elf_fcom_symbol.name = ".fcommon";
863           cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
864           cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
865           cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
866         }
867       asym->section = &cr16c_elf_fcom_section;
868       asym->value = elfsym->internal_elf_sym.st_size;
869       break;
870     case SHN_CR16C_NCOMMON:
871       if (cr16c_elf_ncom_section.name == NULL)
872         {
873           /* Initialize the far common section.  */
874           cr16c_elf_ncom_section.name = ".ncommon";
875           cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
876           cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
877           cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
878           cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
879           cr16c_elf_ncom_symbol.name = ".ncommon";
880           cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
881           cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
882           cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
883         }
884       asym->section = &cr16c_elf_ncom_section;
885       asym->value = elfsym->internal_elf_sym.st_size;
886       break;
887     }
888 }
889
890 /* Hook called by the linker routine which adds symbols from an object
891    file.  We must handle the special cr16c section numbers here.  */
892
893 static bfd_boolean
894 elf32_cr16c_add_symbol_hook (bfd *abfd,
895                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
896                              Elf_Internal_Sym *sym,
897                              const char **namep ATTRIBUTE_UNUSED,
898                              flagword *flagsp ATTRIBUTE_UNUSED,
899                              asection **secp,
900                              bfd_vma *valp)
901 {
902   unsigned int indx = sym->st_shndx;
903
904   switch (indx)
905     {
906     case SHN_CR16C_FCOMMON:
907       *secp = bfd_make_section_old_way (abfd, ".fcommon");
908       (*secp)->flags |= SEC_IS_COMMON;
909       *valp = sym->st_size;
910       break;
911     case SHN_CR16C_NCOMMON:
912       *secp = bfd_make_section_old_way (abfd, ".ncommon");
913       (*secp)->flags |= SEC_IS_COMMON;
914       *valp = sym->st_size;
915       break;
916     }
917
918   return TRUE;
919 }
920
921 static int
922 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
923                                      const char *name ATTRIBUTE_UNUSED,
924                                      Elf_Internal_Sym *sym,
925                                      asection *input_sec,
926                                      struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
927 {
928   /* If we see a common symbol, which implies a relocatable link, then
929      if a symbol was in a special common section in an input file, mark
930      it as a special common in the output file.  */
931
932   if (sym->st_shndx == SHN_COMMON)
933     {
934       if (strcmp (input_sec->name, ".fcommon") == 0)
935         sym->st_shndx = SHN_CR16C_FCOMMON;
936       else if (strcmp (input_sec->name, ".ncommon") == 0)
937         sym->st_shndx = SHN_CR16C_NCOMMON;
938     }
939
940   return 1;
941 }
942
943 /* Definitions for setting CR16C target vector.  */
944 #define TARGET_LITTLE_SYM               cr16c_elf32_vec
945 #define TARGET_LITTLE_NAME              "elf32-cr16c"
946 #define ELF_ARCH                        bfd_arch_cr16c
947 #define ELF_MACHINE_CODE                EM_CR
948 #define ELF_MAXPAGESIZE                 0x1
949 #define elf_symbol_leading_char         '_'
950
951 #define bfd_elf32_bfd_reloc_type_lookup         elf_cr16c_reloc_type_lookup
952 #define bfd_elf32_bfd_reloc_name_lookup elf_cr16c_reloc_name_lookup
953 #define elf_info_to_howto                       elf_cr16c_info_to_howto
954 #define elf_info_to_howto_rel                   elf_cr16c_info_to_howto_rel
955 #define elf_backend_relocate_section            elf32_cr16c_relocate_section
956 #define elf_backend_symbol_processing           elf32_cr16c_symbol_processing
957 #define elf_backend_section_from_bfd_section    elf32_cr16c_section_from_bfd_section
958 #define elf_backend_add_symbol_hook             elf32_cr16c_add_symbol_hook
959 #define elf_backend_link_output_symbol_hook     elf32_cr16c_link_output_symbol_hook
960
961 #define elf_backend_can_gc_sections     1
962
963 #include "elf32-target.h"