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