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