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
44RELOC_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
88static 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
135static reloc_howto_type *
136elf_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
154static reloc_howto_type *
155elf_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
168static void
169elf_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
176static void
177elf_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
194static bfd_reloc_status_type
195cr16c_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
677static bfd_boolean
678elf32_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
812static asection  cr16c_elf_fcom_section;
813static asymbol   cr16c_elf_fcom_symbol;
814static asymbol * cr16c_elf_fcom_symbol_ptr;
815static asection  cr16c_elf_ncom_section;
816static asymbol   cr16c_elf_ncom_symbol;
817static asymbol * cr16c_elf_ncom_symbol_ptr;
818
819/* Given a BFD section, try to locate the
820   corresponding ELF section index.  */
821
822static bfd_boolean
823elf32_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
839static void
840elf32_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
890static bfd_boolean
891elf32_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
918static int
919elf32_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"
961