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