1/* BFD back-end for National Semiconductor's CR16C ELF
2   Copyright 2004, 2005 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
43RELOC_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
87static 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
134static reloc_howto_type *
135elf_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
153static void
154elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
155			 arelent *cache_ptr ATTRIBUTE_UNUSED,
156			 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
157{
158  abort ();
159}
160
161static void
162elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
163			     arelent *cache_ptr,
164			     Elf_Internal_Rela *dst)
165{
166  unsigned int r_type = ELF32_R_TYPE (dst->r_info);
167
168  BFD_ASSERT (r_type < (unsigned int) RINDEX_16C_MAX);
169  cache_ptr->howto = &elf_howto_table[r_type];
170}
171
172/* Perform a relocation as part of a final link.  */
173
174static bfd_reloc_status_type
175cr16c_elf_final_link_relocate (reloc_howto_type *howto,
176			       bfd *abfd,
177			       bfd *output_bfd ATTRIBUTE_UNUSED,
178			       asection *input_section,
179			       bfd_byte *data,
180			       bfd_vma octets,
181			       bfd_vma Rvalue,
182			       bfd_vma addend ATTRIBUTE_UNUSED,
183			       struct bfd_link_info *info ATTRIBUTE_UNUSED,
184			       asection *sym_sec ATTRIBUTE_UNUSED,
185			       int is_local ATTRIBUTE_UNUSED)
186{
187  long value;
188  short sword;			/* Extracted from the hole and put back.  */
189  unsigned long format, addr_type, code_factor;
190  unsigned short size;
191  unsigned short r_type;
192  asymbol *symbol = NULL;
193
194  unsigned long disp20_opcod;
195  char neg = 0;
196  char neg2pos = 0;
197
198  long left_val = 0;
199  long plus_factor = 0;		/* To be added to the hole.  */
200
201#define MIN_BYTE	((int) 0xFFFFFF80)
202#define MIN_WORD	((int) 0xFFFF8000)
203#define	MAX_UWORD	((unsigned) 0x0000FFFF)
204#define	MAX_UBYTE	((unsigned) 0x000000FF)
205
206  r_type = reloc_map_index[howto->type].cr_reloc_type;
207  format = r_type & R_FORMAT;
208  size = r_type & R_SIZESP;
209  addr_type = r_type & R_ADDRTYPE;
210  code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
211
212  if (sym_sec)
213    symbol = sym_sec->symbol;
214
215  switch (format)
216    {
217    case R_NUMBER:
218      switch (size)
219	{
220	case R_S_16C_08: 	/* One byte.  */
221	  value = bfd_get_8 (abfd, (char *) data + octets);
222	  break;
223	case R_S_16C_16: 	/* Two bytes. */
224	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
225	  value = sword;
226	  break;
227	case R_S_16C_32:	/* Four bytes.  */
228	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
229	  break;
230	default:
231	  return bfd_reloc_notsupported;
232	}
233      break;
234
235    case R_16C_DISPL:
236      switch (size)
237	{
238	case R_S_16C_04:    /* word1(4-7).  */
239	  value = bfd_get_8 (abfd, (char *) data + octets);
240	  left_val = value & 0xF;
241	  value = (value & 0xF0) >> 4;
242	  value++;
243	  value <<= 1;
244	  break;
245	case R_S_16C_08:    /* word1(0-3,8-11).  */
246	  sword = bfd_get_16 (abfd, (char *) data + octets);
247	  value = sword & 0x000F;
248	  value |= ((sword & 0x0F00) >> 4);
249	  left_val = sword & 0xF0F0;
250	  value <<= 1;
251	  if (value & 0x100)
252	    value |= 0xFFFFFF00;
253	  break;
254	case R_S_16C_16:    /* word2.  */
255	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
256	  value = sword;
257	  value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15);
258	  value <<= 1;
259	  if (value & 0x10000)
260	    value |= 0xFFFF0000;
261	  break;
262	case R_S_16C_24_a:	/* word1(0-7),word2.  */
263	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
264	  left_val = value & 0x0000FF00;
265	  value = ((value & 0xFFFE0000) >> 17) |
266	    ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15);
267	  value <<= 1;
268	  if (value & 0x1000000)
269	    value |= 0xFE000000;
270	  break;
271	case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
272	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
273	  left_val = value & 0x0000F0F0;
274	  value = ((value >> 16) & 0x0000FFFF) |
275	    ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
276
277	  value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23);
278
279	  value <<= 1;
280	  if (value & 0x1000000)
281	    value |= 0xFE000000;
282	  break;
283	default:
284	  return bfd_reloc_notsupported;
285	}
286      break;
287
288    case R_16C_REGREL:
289      switch (size)
290	{
291	case R_S_16C_04:    /* word1(12-15) not scaled.  */
292	  value = bfd_get_8 (abfd, (char *) data + octets);
293	  left_val = value & 0xF0;
294	  value = value & 0xF;
295	  break;
296	case R_S_16C_04_a:	/* word1(12-15) scaled by 2.  */
297	  value = bfd_get_8 (abfd, (char *) data + octets);
298	  left_val = value & 0xF0;
299	  value = value & 0xF;
300	  value <<= 1;
301	  break;
302	case R_S_16C_14:    /* word1(4-5),word2(0-3,8-15).  */
303	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
304	  left_val = value & 0x00F0FFCF;
305	  value = ((value & 0xc0000000) >> 24) |
306	    ((value & 0x3F000000) >> 16) |
307	    ((value & 0x000F0000) >> 16) | (value & 0x00000030);
308	  break;
309	case R_S_16C_16:    /* word2.  */
310	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
311	  value = sword;
312	  break;
313	case R_S_16C_20:    /* word2(8-11),word3.  */
314	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
315	  left_val = value & 0xF0;
316	  value = (value & 0xF) << 16;
317	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1);
318	  value = value | (unsigned short) sword;
319	  disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3);
320	  disp20_opcod |= 0x0FFF0000;
321	  if ((disp20_opcod == 0x4FFF0018) ||	/* loadb -disp20(reg) */
322	      (disp20_opcod == 0x5FFF0018) ||	/* loadb -disp20(rp)  */
323	      (disp20_opcod == 0x8FFF0018) ||	/* loadd -disp20(reg) */
324	      (disp20_opcod == 0x9FFF0018) ||	/* loadd -disp20(rp)  */
325	      (disp20_opcod == 0xCFFF0018) ||	/* loadw -disp20(reg) */
326	      (disp20_opcod == 0xDFFF0018) ||	/* loadw -disp20(rp)  */
327	      (disp20_opcod == 0x4FFF0019) ||	/* storb -disp20(reg) */
328	      (disp20_opcod == 0x5FFF0019) ||	/* storb -disp20(rp)  */
329	      (disp20_opcod == 0x8FFF0019) ||	/* stord -disp20(reg) */
330	      (disp20_opcod == 0x9FFF0019) ||	/* stord -disp20(rp)  */
331	      (disp20_opcod == 0xCFFF0019) ||	/* storw -disp20(reg) */
332	      (disp20_opcod == 0xDFFF0019))
333	    {	/* storw -disp20(rp).  */
334	      neg = 1;
335	      value |= 0xFFF00000;
336	    }
337
338	  break;
339	default:
340	  return bfd_reloc_notsupported;
341	}
342      break;
343
344    case R_16C_ABS:
345      switch (size)
346	{
347	case R_S_16C_20:    /* word1(0-3),word2.  */
348	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
349	  left_val = value & 0x0000FFF0;
350	  value = ((value & 0xFFFF0000) >> 16) |
351	    ((value & 0x0000000F) << 16);
352	  break;
353	case R_S_16C_24:   /* word2(0-3,8-11),word3.  */
354	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
355	  left_val = value & 0x0000F0F0;
356	  value = ((value & 0xFFFF0000) >> 16) |
357	    ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
358	  break;
359	default:
360	  return bfd_reloc_notsupported;
361	}
362      break;
363
364    case R_16C_IMMED:
365      switch (size)
366	{
367	case R_S_16C_04:    /* word1/2(4-7).  */
368	  value = bfd_get_8 (abfd, (char *) data + octets);
369	  left_val = value & 0xF;
370	  value = (value & 0xF0) >> 4;
371	  break;
372	case R_S_16C_16:    /* word2.  */
373	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
374	  value = sword;
375	  break;
376	case R_S_16C_20:    /* word1(0-3),word2.  */
377	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
378	  left_val = value & 0x0000FFF0;
379	  value = ((value & 0xFFFF0000) >> 16) |
380	    ((value & 0x0000000F) << 16);
381	  break;
382	case R_S_16C_32:    /* word2, word3.  */
383	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
384	  value = ((value & 0x0000FFFF) << 16) |
385	    ((value & 0xFFFF0000) >> 16);
386	  break;
387	default:
388	  return bfd_reloc_notsupported;
389	}
390      break;
391    default:
392      return bfd_reloc_notsupported;
393    }
394
395  switch ((r_type & R_RELTO) >> 4)
396    {
397
398    case 0:	/* R_ABS.  */
399      plus_factor = Rvalue;
400      break;
401    case 1:	/* R_PCREL.  */
402      plus_factor = Rvalue -
403	(input_section->output_section->vma + input_section->output_offset);
404      break;
405    default:
406      return bfd_reloc_notsupported;
407    }
408
409  if (neg)
410    {
411      if (plus_factor >= -value)
412	neg2pos = 1;
413      /* We need to change load/stor with negative
414	 displ opcode to positive disp opcode (CR16C).  */
415    }
416
417  value = value + (plus_factor >> code_factor);
418
419  switch (format)
420    {
421    case R_NUMBER:
422      switch (size)
423	{
424	case R_S_16C_08: 	/* One byte.  */
425	  if (value > (int) MAX_UBYTE || value < MIN_BYTE)
426	    return bfd_reloc_overflow;
427	  value &= 0xFF;
428	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
429	  break;
430
431	case R_S_16C_16:	/* Two bytes.  */
432	  if (value > (int) MAX_UWORD || value < MIN_WORD)
433	    return bfd_reloc_overflow;
434	  value &= 0xFFFF;
435	  sword = value;
436	  bfd_put_16 (abfd, (bfd_vma) sword,
437		      (unsigned char *) data + octets);
438	  break;
439
440	case R_S_16C_32:	/* Four bytes.  */
441	  value &= 0xFFFFFFFF;
442	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
443	  break;
444
445	default:
446	  return bfd_reloc_notsupported;
447	}
448      break;
449
450    case R_16C_DISPL:
451      switch (size)
452	{
453	case R_S_16C_04:	/* word1(4-7).  */
454	  if ((value - 32) > 32 || value < 2)
455	    return bfd_reloc_overflow;
456	  value >>= 1;
457	  value--;
458	  value &= 0xF;
459	  value <<= 4;
460	  value |= left_val;
461	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
462	  break;
463
464	case R_S_16C_08:    /* word1(0-3,8-11).  */
465	  if (value > 255 || value < -256 || value == 0x80)
466	    return bfd_reloc_overflow;
467	  value &= 0x1FF;
468	  value >>= 1;
469	  sword = value & 0x000F;
470	  sword |= (value & 0x00F0) << 4;
471	  sword |= left_val;
472	  bfd_put_16 (abfd, (bfd_vma) sword,
473		      (unsigned char *) data + octets);
474	  break;
475
476	case R_S_16C_16:    /* word2.  */
477	  if (value > 65535 || value < -65536)
478	    return bfd_reloc_overflow;
479	  value >>= 1;
480	  value &= 0xFFFF;
481	  value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1);
482	  sword = value;
483	  bfd_put_16 (abfd, (bfd_vma) sword,
484		      (unsigned char *) data + octets);
485	  break;
486
487	case R_S_16C_24_a:	/* word1(0-7),word2.  */
488	  if (value > 16777215 || value < -16777216)
489	    return bfd_reloc_overflow;
490	  value &= 0x1FFFFFF;
491	  value >>= 1;
492	  value = ((value & 0x00007FFF) << 17) |
493	    ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15);
494	  value |= left_val;
495	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
496	  break;
497
498	case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
499	  if (value > 16777215 || value < -16777216)
500	    return bfd_reloc_overflow;
501	  value &= 0x1FFFFFF;
502	  value >>= 1;
503
504	  value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23);
505
506	  value = ((value & 0x0000FFFF) << 16) |
507	    ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
508	  value |= left_val;
509	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
510	  break;
511
512	default:
513	  return bfd_reloc_notsupported;
514	}
515      break;
516
517    case R_16C_REGREL:
518      switch (size)
519	{
520	case R_S_16C_04:	/* word1(12-15) not scaled.  */
521	  if (value > 13 || value < 0)
522	    return bfd_reloc_overflow;
523	  value &= 0xF;
524	  value |= left_val;
525	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
526	  break;
527
528	case R_S_16C_04_a:	/* word1(12-15) not scaled.  */
529	  if (value > 26 || value < 0)
530	    return bfd_reloc_overflow;
531	  value &= 0x1F;
532	  value >>= 1;
533	  value |= left_val;
534	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
535	  break;
536
537	case R_S_16C_14:	/* word1(4-5),word2(0-3,8-15).  */
538	  if (value < 0 || value > 16383)
539	    return bfd_reloc_overflow;
540	  value &= 0x3FFF;
541	  value = ((value & 0x000000c0) << 24) |
542	    ((value & 0x00003F00) << 16) |
543	    ((value & 0x0000000F) << 16) | (value & 0x00000030);
544	  value |= left_val;
545	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
546	  break;
547
548	case R_S_16C_16:	/* word2.  */
549	  if (value > 65535 || value < 0)
550	    return bfd_reloc_overflow;
551	  value &= 0xFFFF;
552	  sword = value;
553	  bfd_put_16 (abfd, (bfd_vma) sword,
554		      (unsigned char *) data + octets);
555	  break;
556
557	case R_S_16C_20:	/* word2(8-11),word3.  */
558	  /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */
559	  value &= 0xFFFFF;
560	  sword = value & 0x0000FFFF;
561	  value = (value & 0x000F0000) >> 16;
562	  value |= left_val;
563	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
564	  bfd_put_16 (abfd, (bfd_vma) sword,
565		      (unsigned char *) data + octets + 1);
566	  if (neg2pos)
567	    {
568	      /* Change load/stor negative displ opcode
569	         to load/stor positive displ opcode.  */
570	      value = bfd_get_8 (abfd, (char *) data + octets - 3);
571	      value &= 0xF7;
572	      value |= 0x2;
573	      bfd_put_8 (abfd, (bfd_vma) value,
574			 (unsigned char *) data + octets - 3);
575	    }
576	  break;
577
578	default:
579	  return bfd_reloc_notsupported;
580	}
581      break;
582
583    case R_16C_ABS:
584      switch (size)
585	{
586	case R_S_16C_20:	/* word1(0-3),word2.  */
587	  if (value > 1048575 || value < 0)
588	    return bfd_reloc_overflow;
589	  value &= 0xFFFFF;
590	  value = ((value & 0x0000FFFF) << 16) |
591	    ((value & 0x000F0000) >> 16);
592	  value |= left_val;
593	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
594	  break;
595
596	case R_S_16C_24:	/* word2(0-3,8-11),word3.  */
597	  /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */
598	  value &= 0xFFFFFF;
599	  value = ((value & 0x0000FFFF) << 16) |
600	    ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
601	  value |= left_val;
602	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
603	  break;
604
605	default:
606	  return bfd_reloc_notsupported;
607	}
608      break;
609
610    case R_16C_IMMED:
611      switch (size)
612	{
613	case R_S_16C_04:	/* word1/2(4-7).  */
614	  if (value > 15 || value < -1)
615	    return bfd_reloc_overflow;
616	  value &= 0xF;
617	  value <<= 4;
618	  value |= left_val;
619	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
620	  break;
621
622	case R_S_16C_16:	/* word2.  */
623	  if (value > 32767 || value < -32768)
624	    return bfd_reloc_overflow;
625	  value &= 0xFFFF;
626	  sword = value;
627	  bfd_put_16 (abfd, (bfd_vma) sword,
628		      (unsigned char *) data + octets);
629	  break;
630
631	case R_S_16C_20:	/* word1(0-3),word2.  */
632	  if (value > 1048575 || value < 0)
633	    return bfd_reloc_overflow;
634	  value &= 0xFFFFF;
635	  value = ((value & 0x0000FFFF) << 16) |
636	    ((value & 0x000F0000) >> 16);
637	  value |= left_val;
638	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
639	  break;
640
641	case R_S_16C_32:	/* word2, word3.  */
642	  value &= 0xFFFFFFFF;
643	  value = ((value & 0x0000FFFF) << 16) |
644	    ((value & 0xFFFF0000) >> 16);
645	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
646	  break;
647
648	default:
649	  return bfd_reloc_notsupported;
650	}
651      break;
652    default:
653      return bfd_reloc_notsupported;
654    }
655
656  return bfd_reloc_ok;
657}
658
659/* Relocate a CR16C ELF section.  */
660
661static bfd_boolean
662elf32_cr16c_relocate_section (bfd *output_bfd,
663			      struct bfd_link_info *info,
664			      bfd *input_bfd,
665			      asection *input_section,
666			      bfd_byte *contents,
667			      Elf_Internal_Rela *relocs,
668			      Elf_Internal_Sym *local_syms,
669			      asection **local_sections)
670{
671  Elf_Internal_Shdr *symtab_hdr;
672  struct elf_link_hash_entry **sym_hashes;
673  Elf_Internal_Rela *rel, *relend;
674
675  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
676  sym_hashes = elf_sym_hashes (input_bfd);
677
678  rel = relocs;
679  relend = relocs + input_section->reloc_count;
680  for (; rel < relend; rel++)
681    {
682      int r_type;
683      reloc_howto_type *howto;
684      unsigned long r_symndx;
685      Elf_Internal_Sym *sym;
686      asection *sec;
687      struct elf_link_hash_entry *h;
688      bfd_vma relocation;
689      bfd_reloc_status_type r;
690
691      r_symndx = ELF32_R_SYM (rel->r_info);
692      r_type = ELF32_R_TYPE (rel->r_info);
693      howto = elf_howto_table + r_type;
694
695      if (info->relocatable)
696	{
697	  /* This is a relocatable link.  We don't have to change
698	     anything, unless the reloc is against a section symbol,
699	     in which case we have to adjust according to where the
700	     section symbol winds up in the output section.  */
701	  if (r_symndx < symtab_hdr->sh_info)
702	    {
703	      sym = local_syms + r_symndx;
704	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
705		{
706		  sec = local_sections[r_symndx];
707		  rel->r_addend += sec->output_offset + sym->st_value;
708		}
709	    }
710
711	  continue;
712	}
713
714      /* This is a final link.  */
715      h = NULL;
716      sym = NULL;
717      sec = NULL;
718      if (r_symndx < symtab_hdr->sh_info)
719	{
720	  sym = local_syms + r_symndx;
721	  sec = local_sections[r_symndx];
722	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
723	}
724      else
725	{
726	  bfd_boolean unresolved_reloc, warned;
727
728	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
729				   r_symndx, symtab_hdr, sym_hashes,
730				   h, sec, relocation,
731				   unresolved_reloc, warned);
732	}
733
734      r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
735					 input_section,
736					 contents, rel->r_offset,
737					 relocation, rel->r_addend,
738					 info, sec, h == NULL);
739
740      if (r != bfd_reloc_ok)
741	{
742	  const char *name;
743	  const char *msg = (const char *) 0;
744
745	  if (h != NULL)
746	    name = h->root.root.string;
747	  else
748	    {
749	      name = (bfd_elf_string_from_elf_section
750		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
751	      if (name == NULL || *name == '\0')
752		name = bfd_section_name (input_bfd, sec);
753	    }
754
755	  switch (r)
756	    {
757	    case bfd_reloc_overflow:
758	      if (!((*info->callbacks->reloc_overflow)
759		    (info, (h ? &h->root : NULL), name, howto->name,
760		     (bfd_vma) 0, input_bfd, input_section,
761		     rel->r_offset)))
762		return FALSE;
763	      break;
764
765	    case bfd_reloc_undefined:
766	      if (!((*info->callbacks->undefined_symbol)
767		    (info, name, input_bfd, input_section,
768		     rel->r_offset, TRUE)))
769		return FALSE;
770	      break;
771
772	    case bfd_reloc_outofrange:
773	      msg = _("internal error: out of range error");
774	      goto common_error;
775
776	    case bfd_reloc_notsupported:
777	      msg = _("internal error: unsupported relocation error");
778	      goto common_error;
779
780	    case bfd_reloc_dangerous:
781	      msg = _("internal error: dangerous error");
782	      goto common_error;
783
784	    default:
785	      msg = _("internal error: unknown error");
786	      /* fall through */
787
788	    common_error:
789	      if (!((*info->callbacks->warning)
790		    (info, msg, name, input_bfd, input_section,
791		     rel->r_offset)))
792		return FALSE;
793	      break;
794	    }
795	}
796    }
797
798  return TRUE;
799}
800
801static asection *
802elf32_cr16c_gc_mark_hook (asection *sec,
803			  struct bfd_link_info *info ATTRIBUTE_UNUSED,
804			  Elf_Internal_Rela *rel,
805			  struct elf_link_hash_entry *h,
806			  Elf_Internal_Sym *sym)
807{
808  if (h != NULL)
809    {
810      switch (ELF32_R_TYPE (rel->r_info))
811	{
812
813	default:
814	  switch (h->root.type)
815	    {
816	    case bfd_link_hash_defined:
817	    case bfd_link_hash_defweak:
818	      return h->root.u.def.section;
819
820	    case bfd_link_hash_common:
821	      return h->root.u.c.p->section;
822
823	    default:
824	      break;
825	    }
826	}
827    }
828  else
829    {
830      return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
831    }
832
833  return NULL;
834}
835
836/* Update the got entry reference counts for the section being removed.  */
837
838static bfd_boolean
839elf32_cr16c_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
840			   struct bfd_link_info *info ATTRIBUTE_UNUSED,
841			   asection *sec ATTRIBUTE_UNUSED,
842			   const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
843{
844  /* We don't support garbage collection of GOT and PLT relocs yet.  */
845  return TRUE;
846}
847
848/* CR16C ELF uses three common sections:
849   One is for default common symbols (placed in usual common section).
850   Second is for near common symbols (placed in "ncommon" section).
851   Third is for far common symbols (placed in "fcommon" section).
852   The following implementation is based on elf32-mips architecture */
853
854static asection  cr16c_elf_fcom_section;
855static asymbol   cr16c_elf_fcom_symbol;
856static asymbol * cr16c_elf_fcom_symbol_ptr;
857static asection  cr16c_elf_ncom_section;
858static asymbol   cr16c_elf_ncom_symbol;
859static asymbol * cr16c_elf_ncom_symbol_ptr;
860
861/* Given a BFD section, try to locate the
862   corresponding ELF section index.  */
863
864static bfd_boolean
865elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
866				      asection *sec,
867				      int *retval)
868{
869  if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
870    *retval = SHN_CR16C_FCOMMON;
871  else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
872    *retval = SHN_CR16C_NCOMMON;
873  else
874    return FALSE;
875
876  return TRUE;
877}
878
879/* Handle the special CR16C section numbers that a symbol may use.  */
880
881static void
882elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
883			       asymbol *asym)
884{
885  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
886  unsigned int indx;
887
888  indx = elfsym->internal_elf_sym.st_shndx;
889
890  switch (indx)
891    {
892    case SHN_CR16C_FCOMMON:
893      if (cr16c_elf_fcom_section.name == NULL)
894	{
895	  /* Initialize the far common section.  */
896	  cr16c_elf_fcom_section.name = ".fcommon";
897	  cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
898	  cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
899	  cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
900	  cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
901	  cr16c_elf_fcom_symbol.name = ".fcommon";
902	  cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
903	  cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
904	  cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
905	}
906      asym->section = &cr16c_elf_fcom_section;
907      asym->value = elfsym->internal_elf_sym.st_size;
908      break;
909    case SHN_CR16C_NCOMMON:
910      if (cr16c_elf_ncom_section.name == NULL)
911	{
912	  /* Initialize the far common section.  */
913	  cr16c_elf_ncom_section.name = ".ncommon";
914	  cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
915	  cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
916	  cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
917	  cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
918	  cr16c_elf_ncom_symbol.name = ".ncommon";
919	  cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
920	  cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
921	  cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
922	}
923      asym->section = &cr16c_elf_ncom_section;
924      asym->value = elfsym->internal_elf_sym.st_size;
925      break;
926    }
927}
928
929/* Hook called by the linker routine which adds symbols from an object
930   file.  We must handle the special cr16c section numbers here.  */
931
932static bfd_boolean
933elf32_cr16c_add_symbol_hook (bfd *abfd,
934			     struct bfd_link_info *info ATTRIBUTE_UNUSED,
935			     Elf_Internal_Sym *sym,
936			     const char **namep ATTRIBUTE_UNUSED,
937			     flagword *flagsp ATTRIBUTE_UNUSED,
938			     asection **secp,
939			     bfd_vma *valp)
940{
941  unsigned int indx = sym->st_shndx;
942
943  switch (indx)
944    {
945    case SHN_CR16C_FCOMMON:
946      *secp = bfd_make_section_old_way (abfd, ".fcommon");
947      (*secp)->flags |= SEC_IS_COMMON;
948      *valp = sym->st_size;
949      break;
950    case SHN_CR16C_NCOMMON:
951      *secp = bfd_make_section_old_way (abfd, ".ncommon");
952      (*secp)->flags |= SEC_IS_COMMON;
953      *valp = sym->st_size;
954      break;
955    }
956
957  return TRUE;
958}
959
960static bfd_boolean
961elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
962				     const char *name ATTRIBUTE_UNUSED,
963				     Elf_Internal_Sym *sym,
964				     asection *input_sec,
965				     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
966{
967  /* If we see a common symbol, which implies a relocatable link, then
968     if a symbol was in a special common section in an input file, mark
969     it as a special common in the output file.  */
970
971  if (sym->st_shndx == SHN_COMMON)
972    {
973      if (strcmp (input_sec->name, ".fcommon") == 0)
974	sym->st_shndx = SHN_CR16C_FCOMMON;
975      else if (strcmp (input_sec->name, ".ncommon") == 0)
976	sym->st_shndx = SHN_CR16C_NCOMMON;
977    }
978
979  return TRUE;
980}
981
982/* Definitions for setting CR16C target vector.  */
983#define TARGET_LITTLE_SYM		bfd_elf32_cr16c_vec
984#define TARGET_LITTLE_NAME		"elf32-cr16c"
985#define ELF_ARCH			bfd_arch_cr16c
986#define ELF_MACHINE_CODE		EM_CR
987#define ELF_MAXPAGESIZE			0x1
988#define elf_symbol_leading_char		'_'
989
990#define bfd_elf32_bfd_reloc_type_lookup		elf_cr16c_reloc_type_lookup
991#define elf_info_to_howto			elf_cr16c_info_to_howto
992#define elf_info_to_howto_rel			elf_cr16c_info_to_howto_rel
993#define elf_backend_relocate_section		elf32_cr16c_relocate_section
994#define elf_backend_gc_mark_hook        	elf32_cr16c_gc_mark_hook
995#define elf_backend_gc_sweep_hook       	elf32_cr16c_gc_sweep_hook
996#define elf_backend_symbol_processing		elf32_cr16c_symbol_processing
997#define elf_backend_section_from_bfd_section 	elf32_cr16c_section_from_bfd_section
998#define elf_backend_add_symbol_hook		elf32_cr16c_add_symbol_hook
999#define elf_backend_link_output_symbol_hook 	elf32_cr16c_link_output_symbol_hook
1000
1001#define elf_backend_can_gc_sections     1
1002
1003#include "elf32-target.h"
1004