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