daily update
[external/binutils.git] / bfd / elf32-cr16c.c
1 /* BFD back-end for National Semiconductor's CR16C ELF
2    Copyright 2004, 2005, 2006, 2007 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   asymbol *symbol = NULL;
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   if (sym_sec)
228     symbol = sym_sec->symbol;
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;
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);
727         }
728
729       if (sec != NULL && elf_discarded_section (sec))
730         {
731           /* For relocs against symbols from removed linkonce sections,
732              or sections discarded by a linker script, we just want the
733              section contents zeroed.  Avoid any special processing.  */
734           _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
735           rel->r_info = 0;
736           rel->r_addend = 0;
737           continue;
738         }
739
740       if (info->relocatable)
741         {
742           /* This is a relocatable link.  We don't have to change
743              anything, unless the reloc is against a section symbol,
744              in which case we have to adjust according to where the
745              section symbol winds up in the output section.  */
746           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
747             rel->r_addend += sec->output_offset;
748           continue;
749         }
750
751       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
752                                          input_section,
753                                          contents, rel->r_offset,
754                                          relocation, rel->r_addend,
755                                          info, sec, h == NULL);
756
757       if (r != bfd_reloc_ok)
758         {
759           const char *name;
760           const char *msg = (const char *) 0;
761
762           if (h != NULL)
763             name = h->root.root.string;
764           else
765             {
766               name = (bfd_elf_string_from_elf_section
767                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
768               if (name == NULL || *name == '\0')
769                 name = bfd_section_name (input_bfd, sec);
770             }
771
772           switch (r)
773             {
774             case bfd_reloc_overflow:
775               if (!((*info->callbacks->reloc_overflow)
776                     (info, (h ? &h->root : NULL), name, howto->name,
777                      (bfd_vma) 0, input_bfd, input_section,
778                      rel->r_offset)))
779                 return FALSE;
780               break;
781
782             case bfd_reloc_undefined:
783               if (!((*info->callbacks->undefined_symbol)
784                     (info, name, input_bfd, input_section,
785                      rel->r_offset, TRUE)))
786                 return FALSE;
787               break;
788
789             case bfd_reloc_outofrange:
790               msg = _("internal error: out of range error");
791               goto common_error;
792
793             case bfd_reloc_notsupported:
794               msg = _("internal error: unsupported relocation error");
795               goto common_error;
796
797             case bfd_reloc_dangerous:
798               msg = _("internal error: dangerous error");
799               goto common_error;
800
801             default:
802               msg = _("internal error: unknown error");
803               /* fall through */
804
805             common_error:
806               if (!((*info->callbacks->warning)
807                     (info, msg, name, input_bfd, input_section,
808                      rel->r_offset)))
809                 return FALSE;
810               break;
811             }
812         }
813     }
814
815   return TRUE;
816 }
817
818 /* CR16C ELF uses three common sections:
819    One is for default common symbols (placed in usual common section).
820    Second is for near common symbols (placed in "ncommon" section).
821    Third is for far common symbols (placed in "fcommon" section).
822    The following implementation is based on elf32-mips architecture */
823
824 static asection  cr16c_elf_fcom_section;
825 static asymbol   cr16c_elf_fcom_symbol;
826 static asymbol * cr16c_elf_fcom_symbol_ptr;
827 static asection  cr16c_elf_ncom_section;
828 static asymbol   cr16c_elf_ncom_symbol;
829 static asymbol * cr16c_elf_ncom_symbol_ptr;
830
831 /* Given a BFD section, try to locate the
832    corresponding ELF section index.  */
833
834 static bfd_boolean
835 elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
836                                       asection *sec,
837                                       int *retval)
838 {
839   if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
840     *retval = SHN_CR16C_FCOMMON;
841   else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
842     *retval = SHN_CR16C_NCOMMON;
843   else
844     return FALSE;
845
846   return TRUE;
847 }
848
849 /* Handle the special CR16C section numbers that a symbol may use.  */
850
851 static void
852 elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
853                                asymbol *asym)
854 {
855   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
856   unsigned int indx;
857
858   indx = elfsym->internal_elf_sym.st_shndx;
859
860   switch (indx)
861     {
862     case SHN_CR16C_FCOMMON:
863       if (cr16c_elf_fcom_section.name == NULL)
864         {
865           /* Initialize the far common section.  */
866           cr16c_elf_fcom_section.name = ".fcommon";
867           cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
868           cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
869           cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
870           cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
871           cr16c_elf_fcom_symbol.name = ".fcommon";
872           cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
873           cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
874           cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
875         }
876       asym->section = &cr16c_elf_fcom_section;
877       asym->value = elfsym->internal_elf_sym.st_size;
878       break;
879     case SHN_CR16C_NCOMMON:
880       if (cr16c_elf_ncom_section.name == NULL)
881         {
882           /* Initialize the far common section.  */
883           cr16c_elf_ncom_section.name = ".ncommon";
884           cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
885           cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
886           cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
887           cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
888           cr16c_elf_ncom_symbol.name = ".ncommon";
889           cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
890           cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
891           cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
892         }
893       asym->section = &cr16c_elf_ncom_section;
894       asym->value = elfsym->internal_elf_sym.st_size;
895       break;
896     }
897 }
898
899 /* Hook called by the linker routine which adds symbols from an object
900    file.  We must handle the special cr16c section numbers here.  */
901
902 static bfd_boolean
903 elf32_cr16c_add_symbol_hook (bfd *abfd,
904                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
905                              Elf_Internal_Sym *sym,
906                              const char **namep ATTRIBUTE_UNUSED,
907                              flagword *flagsp ATTRIBUTE_UNUSED,
908                              asection **secp,
909                              bfd_vma *valp)
910 {
911   unsigned int indx = sym->st_shndx;
912
913   switch (indx)
914     {
915     case SHN_CR16C_FCOMMON:
916       *secp = bfd_make_section_old_way (abfd, ".fcommon");
917       (*secp)->flags |= SEC_IS_COMMON;
918       *valp = sym->st_size;
919       break;
920     case SHN_CR16C_NCOMMON:
921       *secp = bfd_make_section_old_way (abfd, ".ncommon");
922       (*secp)->flags |= SEC_IS_COMMON;
923       *valp = sym->st_size;
924       break;
925     }
926
927   return TRUE;
928 }
929
930 static bfd_boolean
931 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
932                                      const char *name ATTRIBUTE_UNUSED,
933                                      Elf_Internal_Sym *sym,
934                                      asection *input_sec,
935                                      struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
936 {
937   /* If we see a common symbol, which implies a relocatable link, then
938      if a symbol was in a special common section in an input file, mark
939      it as a special common in the output file.  */
940
941   if (sym->st_shndx == SHN_COMMON)
942     {
943       if (strcmp (input_sec->name, ".fcommon") == 0)
944         sym->st_shndx = SHN_CR16C_FCOMMON;
945       else if (strcmp (input_sec->name, ".ncommon") == 0)
946         sym->st_shndx = SHN_CR16C_NCOMMON;
947     }
948
949   return TRUE;
950 }
951
952 /* Definitions for setting CR16C target vector.  */
953 #define TARGET_LITTLE_SYM               bfd_elf32_cr16c_vec
954 #define TARGET_LITTLE_NAME              "elf32-cr16c"
955 #define ELF_ARCH                        bfd_arch_cr16c
956 #define ELF_MACHINE_CODE                EM_CR
957 #define ELF_MAXPAGESIZE                 0x1
958 #define elf_symbol_leading_char         '_'
959
960 #define bfd_elf32_bfd_reloc_type_lookup         elf_cr16c_reloc_type_lookup
961 #define bfd_elf32_bfd_reloc_name_lookup elf_cr16c_reloc_name_lookup
962 #define elf_info_to_howto                       elf_cr16c_info_to_howto
963 #define elf_info_to_howto_rel                   elf_cr16c_info_to_howto_rel
964 #define elf_backend_relocate_section            elf32_cr16c_relocate_section
965 #define elf_backend_symbol_processing           elf32_cr16c_symbol_processing
966 #define elf_backend_section_from_bfd_section    elf32_cr16c_section_from_bfd_section
967 #define elf_backend_add_symbol_hook             elf32_cr16c_add_symbol_hook
968 #define elf_backend_link_output_symbol_hook     elf32_cr16c_link_output_symbol_hook
969
970 #define elf_backend_can_gc_sections     1
971
972 #include "elf32-target.h"