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