Automatic date update in version.in
[platform/upstream/binutils.git] / bfd / elf32-cr16c.c
1 /* BFD back-end for National Semiconductor's CR16C ELF
2    Copyright (C) 2004-2014 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   BFD_ASSERT (r_type < (unsigned int) RINDEX_16C_MAX);
184   cache_ptr->howto = &elf_howto_table[r_type];
185 }
186
187 /* Perform a relocation as part of a final link.  */
188
189 static bfd_reloc_status_type
190 cr16c_elf_final_link_relocate (reloc_howto_type *howto,
191                                bfd *abfd,
192                                bfd *output_bfd ATTRIBUTE_UNUSED,
193                                asection *input_section,
194                                bfd_byte *data,
195                                bfd_vma octets,
196                                bfd_vma Rvalue,
197                                bfd_vma addend ATTRIBUTE_UNUSED,
198                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
199                                asection *sym_sec ATTRIBUTE_UNUSED,
200                                int is_local ATTRIBUTE_UNUSED)
201 {
202   long value;
203   short sword;                  /* Extracted from the hole and put back.  */
204   unsigned long format, addr_type, code_factor;
205   unsigned short size;
206   unsigned short r_type;
207
208   unsigned long disp20_opcod;
209   char neg = 0;
210   char neg2pos = 0;
211
212   long left_val = 0;
213   long plus_factor = 0;         /* To be added to the hole.  */
214
215 #define MIN_BYTE        ((int) 0xFFFFFF80)
216 #define MIN_WORD        ((int) 0xFFFF8000)
217 #define MAX_UWORD       ((unsigned) 0x0000FFFF)
218 #define MAX_UBYTE       ((unsigned) 0x000000FF)
219
220   r_type = reloc_map_index[howto->type].cr_reloc_type;
221   format = r_type & R_FORMAT;
222   size = r_type & R_SIZESP;
223   addr_type = r_type & R_ADDRTYPE;
224   code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
225
226   switch (format)
227     {
228     case R_NUMBER:
229       switch (size)
230         {
231         case R_S_16C_08:        /* One byte.  */
232           value = bfd_get_8 (abfd, (char *) data + octets);
233           break;
234         case R_S_16C_16:        /* Two bytes. */
235           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
236           value = sword;
237           break;
238         case R_S_16C_32:        /* Four bytes.  */
239           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
240           break;
241         default:
242           return bfd_reloc_notsupported;
243         }
244       break;
245
246     case R_16C_DISPL:
247       switch (size)
248         {
249         case R_S_16C_04:    /* word1(4-7).  */
250           value = bfd_get_8 (abfd, (char *) data + octets);
251           left_val = value & 0xF;
252           value = (value & 0xF0) >> 4;
253           value++;
254           value <<= 1;
255           break;
256         case R_S_16C_08:    /* word1(0-3,8-11).  */
257           sword = bfd_get_16 (abfd, (char *) data + octets);
258           value = sword & 0x000F;
259           value |= ((sword & 0x0F00) >> 4);
260           left_val = sword & 0xF0F0;
261           value <<= 1;
262           if (value & 0x100)
263             value |= 0xFFFFFF00;
264           break;
265         case R_S_16C_16:    /* word2.  */
266           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
267           value = sword;
268           value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15);
269           value <<= 1;
270           if (value & 0x10000)
271             value |= 0xFFFF0000;
272           break;
273         case R_S_16C_24_a:      /* word1(0-7),word2.  */
274           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
275           left_val = value & 0x0000FF00;
276           value = ((value & 0xFFFE0000) >> 17) |
277             ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15);
278           value <<= 1;
279           if (value & 0x1000000)
280             value |= 0xFE000000;
281           break;
282         case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
283           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
284           left_val = value & 0x0000F0F0;
285           value = ((value >> 16) & 0x0000FFFF) |
286             ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
287
288           value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23);
289
290           value <<= 1;
291           if (value & 0x1000000)
292             value |= 0xFE000000;
293           break;
294         default:
295           return bfd_reloc_notsupported;
296         }
297       break;
298
299     case R_16C_REGREL:
300       switch (size)
301         {
302         case R_S_16C_04:    /* word1(12-15) not scaled.  */
303           value = bfd_get_8 (abfd, (char *) data + octets);
304           left_val = value & 0xF0;
305           value = value & 0xF;
306           break;
307         case R_S_16C_04_a:      /* word1(12-15) scaled by 2.  */
308           value = bfd_get_8 (abfd, (char *) data + octets);
309           left_val = value & 0xF0;
310           value = value & 0xF;
311           value <<= 1;
312           break;
313         case R_S_16C_14:    /* word1(4-5),word2(0-3,8-15).  */
314           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
315           left_val = value & 0x00F0FFCF;
316           value = ((value & 0xc0000000) >> 24) |
317             ((value & 0x3F000000) >> 16) |
318             ((value & 0x000F0000) >> 16) | (value & 0x00000030);
319           break;
320         case R_S_16C_16:    /* word2.  */
321           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
322           value = sword;
323           break;
324         case R_S_16C_20:    /* word2(8-11),word3.  */
325           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
326           left_val = value & 0xF0;
327           value = (value & 0xF) << 16;
328           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1);
329           value = value | (unsigned short) sword;
330           disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3);
331           disp20_opcod |= 0x0FFF0000;
332           if ((disp20_opcod == 0x4FFF0018) ||   /* loadb -disp20(reg) */
333               (disp20_opcod == 0x5FFF0018) ||   /* loadb -disp20(rp)  */
334               (disp20_opcod == 0x8FFF0018) ||   /* loadd -disp20(reg) */
335               (disp20_opcod == 0x9FFF0018) ||   /* loadd -disp20(rp)  */
336               (disp20_opcod == 0xCFFF0018) ||   /* loadw -disp20(reg) */
337               (disp20_opcod == 0xDFFF0018) ||   /* loadw -disp20(rp)  */
338               (disp20_opcod == 0x4FFF0019) ||   /* storb -disp20(reg) */
339               (disp20_opcod == 0x5FFF0019) ||   /* storb -disp20(rp)  */
340               (disp20_opcod == 0x8FFF0019) ||   /* stord -disp20(reg) */
341               (disp20_opcod == 0x9FFF0019) ||   /* stord -disp20(rp)  */
342               (disp20_opcod == 0xCFFF0019) ||   /* storw -disp20(reg) */
343               (disp20_opcod == 0xDFFF0019))
344             {   /* storw -disp20(rp).  */
345               neg = 1;
346               value |= 0xFFF00000;
347             }
348
349           break;
350         default:
351           return bfd_reloc_notsupported;
352         }
353       break;
354
355     case R_16C_ABS:
356       switch (size)
357         {
358         case R_S_16C_20:    /* word1(0-3),word2.  */
359           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
360           left_val = value & 0x0000FFF0;
361           value = ((value & 0xFFFF0000) >> 16) |
362             ((value & 0x0000000F) << 16);
363           break;
364         case R_S_16C_24:   /* word2(0-3,8-11),word3.  */
365           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
366           left_val = value & 0x0000F0F0;
367           value = ((value & 0xFFFF0000) >> 16) |
368             ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
369           break;
370         default:
371           return bfd_reloc_notsupported;
372         }
373       break;
374
375     case R_16C_IMMED:
376       switch (size)
377         {
378         case R_S_16C_04:    /* word1/2(4-7).  */
379           value = bfd_get_8 (abfd, (char *) data + octets);
380           left_val = value & 0xF;
381           value = (value & 0xF0) >> 4;
382           break;
383         case R_S_16C_16:    /* word2.  */
384           sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
385           value = sword;
386           break;
387         case R_S_16C_20:    /* word1(0-3),word2.  */
388           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
389           left_val = value & 0x0000FFF0;
390           value = ((value & 0xFFFF0000) >> 16) |
391             ((value & 0x0000000F) << 16);
392           break;
393         case R_S_16C_32:    /* word2, word3.  */
394           value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
395           value = ((value & 0x0000FFFF) << 16) |
396             ((value & 0xFFFF0000) >> 16);
397           break;
398         default:
399           return bfd_reloc_notsupported;
400         }
401       break;
402     default:
403       return bfd_reloc_notsupported;
404     }
405
406   switch ((r_type & R_RELTO) >> 4)
407     {
408
409     case 0:     /* R_ABS.  */
410       plus_factor = Rvalue;
411       break;
412     case 1:     /* R_PCREL.  */
413       plus_factor = Rvalue -
414         (input_section->output_section->vma + input_section->output_offset);
415       break;
416     default:
417       return bfd_reloc_notsupported;
418     }
419
420   if (neg)
421     {
422       if (plus_factor >= -value)
423         neg2pos = 1;
424       /* We need to change load/stor with negative
425          displ opcode to positive disp opcode (CR16C).  */
426     }
427
428   value = value + (plus_factor >> code_factor);
429
430   switch (format)
431     {
432     case R_NUMBER:
433       switch (size)
434         {
435         case R_S_16C_08:        /* One byte.  */
436           if (value > (int) MAX_UBYTE || value < MIN_BYTE)
437             return bfd_reloc_overflow;
438           value &= 0xFF;
439           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
440           break;
441
442         case R_S_16C_16:        /* Two bytes.  */
443           if (value > (int) MAX_UWORD || value < MIN_WORD)
444             return bfd_reloc_overflow;
445           value &= 0xFFFF;
446           sword = value;
447           bfd_put_16 (abfd, (bfd_vma) sword,
448                       (unsigned char *) data + octets);
449           break;
450
451         case R_S_16C_32:        /* Four bytes.  */
452           value &= 0xFFFFFFFF;
453           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
454           break;
455
456         default:
457           return bfd_reloc_notsupported;
458         }
459       break;
460
461     case R_16C_DISPL:
462       switch (size)
463         {
464         case R_S_16C_04:        /* word1(4-7).  */
465           if ((value - 32) > 32 || value < 2)
466             return bfd_reloc_overflow;
467           value >>= 1;
468           value--;
469           value &= 0xF;
470           value <<= 4;
471           value |= left_val;
472           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
473           break;
474
475         case R_S_16C_08:    /* word1(0-3,8-11).  */
476           if (value > 255 || value < -256 || value == 0x80)
477             return bfd_reloc_overflow;
478           value &= 0x1FF;
479           value >>= 1;
480           sword = value & 0x000F;
481           sword |= (value & 0x00F0) << 4;
482           sword |= left_val;
483           bfd_put_16 (abfd, (bfd_vma) sword,
484                       (unsigned char *) data + octets);
485           break;
486
487         case R_S_16C_16:    /* word2.  */
488           if (value > 65535 || value < -65536)
489             return bfd_reloc_overflow;
490           value >>= 1;
491           value &= 0xFFFF;
492           value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1);
493           sword = value;
494           bfd_put_16 (abfd, (bfd_vma) sword,
495                       (unsigned char *) data + octets);
496           break;
497
498         case R_S_16C_24_a:      /* word1(0-7),word2.  */
499           if (value > 16777215 || value < -16777216)
500             return bfd_reloc_overflow;
501           value &= 0x1FFFFFF;
502           value >>= 1;
503           value = ((value & 0x00007FFF) << 17) |
504             ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15);
505           value |= left_val;
506           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
507           break;
508
509         case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
510           if (value > 16777215 || value < -16777216)
511             return bfd_reloc_overflow;
512           value &= 0x1FFFFFF;
513           value >>= 1;
514
515           value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23);
516
517           value = ((value & 0x0000FFFF) << 16) |
518             ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
519           value |= left_val;
520           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
521           break;
522
523         default:
524           return bfd_reloc_notsupported;
525         }
526       break;
527
528     case R_16C_REGREL:
529       switch (size)
530         {
531         case R_S_16C_04:        /* word1(12-15) not scaled.  */
532           if (value > 13 || value < 0)
533             return bfd_reloc_overflow;
534           value &= 0xF;
535           value |= left_val;
536           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
537           break;
538
539         case R_S_16C_04_a:      /* word1(12-15) not scaled.  */
540           if (value > 26 || value < 0)
541             return bfd_reloc_overflow;
542           value &= 0x1F;
543           value >>= 1;
544           value |= left_val;
545           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
546           break;
547
548         case R_S_16C_14:        /* word1(4-5),word2(0-3,8-15).  */
549           if (value < 0 || value > 16383)
550             return bfd_reloc_overflow;
551           value &= 0x3FFF;
552           value = ((value & 0x000000c0) << 24) |
553             ((value & 0x00003F00) << 16) |
554             ((value & 0x0000000F) << 16) | (value & 0x00000030);
555           value |= left_val;
556           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
557           break;
558
559         case R_S_16C_16:        /* word2.  */
560           if (value > 65535 || value < 0)
561             return bfd_reloc_overflow;
562           value &= 0xFFFF;
563           sword = value;
564           bfd_put_16 (abfd, (bfd_vma) sword,
565                       (unsigned char *) data + octets);
566           break;
567
568         case R_S_16C_20:        /* word2(8-11),word3.  */
569           /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */
570           value &= 0xFFFFF;
571           sword = value & 0x0000FFFF;
572           value = (value & 0x000F0000) >> 16;
573           value |= left_val;
574           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
575           bfd_put_16 (abfd, (bfd_vma) sword,
576                       (unsigned char *) data + octets + 1);
577           if (neg2pos)
578             {
579               /* Change load/stor negative displ opcode
580                  to load/stor positive displ opcode.  */
581               value = bfd_get_8 (abfd, (char *) data + octets - 3);
582               value &= 0xF7;
583               value |= 0x2;
584               bfd_put_8 (abfd, (bfd_vma) value,
585                          (unsigned char *) data + octets - 3);
586             }
587           break;
588
589         default:
590           return bfd_reloc_notsupported;
591         }
592       break;
593
594     case R_16C_ABS:
595       switch (size)
596         {
597         case R_S_16C_20:        /* word1(0-3),word2.  */
598           if (value > 1048575 || value < 0)
599             return bfd_reloc_overflow;
600           value &= 0xFFFFF;
601           value = ((value & 0x0000FFFF) << 16) |
602             ((value & 0x000F0000) >> 16);
603           value |= left_val;
604           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
605           break;
606
607         case R_S_16C_24:        /* word2(0-3,8-11),word3.  */
608           /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */
609           value &= 0xFFFFFF;
610           value = ((value & 0x0000FFFF) << 16) |
611             ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
612           value |= left_val;
613           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
614           break;
615
616         default:
617           return bfd_reloc_notsupported;
618         }
619       break;
620
621     case R_16C_IMMED:
622       switch (size)
623         {
624         case R_S_16C_04:        /* word1/2(4-7).  */
625           if (value > 15 || value < -1)
626             return bfd_reloc_overflow;
627           value &= 0xF;
628           value <<= 4;
629           value |= left_val;
630           bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
631           break;
632
633         case R_S_16C_16:        /* word2.  */
634           if (value > 32767 || value < -32768)
635             return bfd_reloc_overflow;
636           value &= 0xFFFF;
637           sword = value;
638           bfd_put_16 (abfd, (bfd_vma) sword,
639                       (unsigned char *) data + octets);
640           break;
641
642         case R_S_16C_20:        /* word1(0-3),word2.  */
643           if (value > 1048575 || value < 0)
644             return bfd_reloc_overflow;
645           value &= 0xFFFFF;
646           value = ((value & 0x0000FFFF) << 16) |
647             ((value & 0x000F0000) >> 16);
648           value |= left_val;
649           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
650           break;
651
652         case R_S_16C_32:        /* word2, word3.  */
653           value &= 0xFFFFFFFF;
654           value = ((value & 0x0000FFFF) << 16) |
655             ((value & 0xFFFF0000) >> 16);
656           bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
657           break;
658
659         default:
660           return bfd_reloc_notsupported;
661         }
662       break;
663     default:
664       return bfd_reloc_notsupported;
665     }
666
667   return bfd_reloc_ok;
668 }
669
670 /* Relocate a CR16C ELF section.  */
671
672 static bfd_boolean
673 elf32_cr16c_relocate_section (bfd *output_bfd,
674                               struct bfd_link_info *info,
675                               bfd *input_bfd,
676                               asection *input_section,
677                               bfd_byte *contents,
678                               Elf_Internal_Rela *relocs,
679                               Elf_Internal_Sym *local_syms,
680                               asection **local_sections)
681 {
682   Elf_Internal_Shdr *symtab_hdr;
683   struct elf_link_hash_entry **sym_hashes;
684   Elf_Internal_Rela *rel, *relend;
685
686   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
687   sym_hashes = elf_sym_hashes (input_bfd);
688
689   rel = relocs;
690   relend = relocs + input_section->reloc_count;
691   for (; rel < relend; rel++)
692     {
693       int r_type;
694       reloc_howto_type *howto;
695       unsigned long r_symndx;
696       Elf_Internal_Sym *sym;
697       asection *sec;
698       struct elf_link_hash_entry *h;
699       bfd_vma relocation;
700       bfd_reloc_status_type r;
701
702       r_symndx = ELF32_R_SYM (rel->r_info);
703       r_type = ELF32_R_TYPE (rel->r_info);
704       howto = elf_howto_table + r_type;
705
706       h = NULL;
707       sym = NULL;
708       sec = NULL;
709       if (r_symndx < symtab_hdr->sh_info)
710         {
711           sym = local_syms + r_symndx;
712           sec = local_sections[r_symndx];
713           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
714         }
715       else
716         {
717           bfd_boolean unresolved_reloc, warned, ignored;
718
719           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
720                                    r_symndx, symtab_hdr, sym_hashes,
721                                    h, sec, relocation,
722                                    unresolved_reloc, warned, ignored);
723         }
724
725       if (sec != NULL && discarded_section (sec))
726         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
727                                          rel, 1, relend, howto, 0, contents);
728
729       if (info->relocatable)
730         {
731           /* This is a relocatable link.  We don't have to change
732              anything, unless the reloc is against a section symbol,
733              in which case we have to adjust according to where the
734              section symbol winds up in the output section.  */
735           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
736             rel->r_addend += sec->output_offset;
737           continue;
738         }
739
740       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
741                                          input_section,
742                                          contents, rel->r_offset,
743                                          relocation, rel->r_addend,
744                                          info, sec, h == NULL);
745
746       if (r != bfd_reloc_ok)
747         {
748           const char *name;
749           const char *msg = (const char *) 0;
750
751           if (h != NULL)
752             name = h->root.root.string;
753           else
754             {
755               name = (bfd_elf_string_from_elf_section
756                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
757               if (name == NULL || *name == '\0')
758                 name = bfd_section_name (input_bfd, sec);
759             }
760
761           switch (r)
762             {
763             case bfd_reloc_overflow:
764               if (!((*info->callbacks->reloc_overflow)
765                     (info, (h ? &h->root : NULL), name, howto->name,
766                      (bfd_vma) 0, input_bfd, input_section,
767                      rel->r_offset)))
768                 return FALSE;
769               break;
770
771             case bfd_reloc_undefined:
772               if (!((*info->callbacks->undefined_symbol)
773                     (info, name, input_bfd, input_section,
774                      rel->r_offset, TRUE)))
775                 return FALSE;
776               break;
777
778             case bfd_reloc_outofrange:
779               msg = _("internal error: out of range error");
780               goto common_error;
781
782             case bfd_reloc_notsupported:
783               msg = _("internal error: unsupported relocation error");
784               goto common_error;
785
786             case bfd_reloc_dangerous:
787               msg = _("internal error: dangerous error");
788               goto common_error;
789
790             default:
791               msg = _("internal error: unknown error");
792               /* fall through */
793
794             common_error:
795               if (!((*info->callbacks->warning)
796                     (info, msg, name, input_bfd, input_section,
797                      rel->r_offset)))
798                 return FALSE;
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"