1 /* BFD back-end for National Semiconductor's CR16C ELF
2    Copyright (C) 2004-2016 Free Software Foundation, Inc.
3 
4    This file is part of BFD, the Binary File Descriptor library.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20 
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "libbfd.h"
24 #include "bfdlink.h"
25 #include "elf/cr16c.h"
26 #include "elf-bfd.h"
27 
28 
29 #define USE_REL	1	/* CR16C uses REL relocations instead of RELA.  */
30 
31 /* The following definition is based on EMPTY_HOWTO macro,
32    but also initiates the "name" field in HOWTO struct.  */
33 #define ONLY_NAME_HOWTO(C) \
34   HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
35 	  STRINGX(C), FALSE, 0, 0, FALSE)
36 
37 /* reloc_map_index array maps CRASM relocation type into a BFD
38    relocation enum. The array's indices are synchronized with
39    RINDEX_16C_* indices, created in include/elf/cr16c.h.
40    The array is used in:
41    1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup().
42    2. asreloc.c : find_reloc_type(). */
43 
44 RELOC_MAP reloc_map_index[RINDEX_16C_MAX] =
45 {
46   {R_16C_NUM08,     BFD_RELOC_16C_NUM08},
47   {R_16C_NUM08_C,   BFD_RELOC_16C_NUM08_C},
48   {R_16C_NUM16,     BFD_RELOC_16C_NUM16},
49   {R_16C_NUM16_C,   BFD_RELOC_16C_NUM16_C},
50   {R_16C_NUM32,     BFD_RELOC_16C_NUM32},
51   {R_16C_NUM32_C,   BFD_RELOC_16C_NUM32_C},
52   {R_16C_DISP04,    BFD_RELOC_16C_DISP04},
53   {R_16C_DISP04_C,  BFD_RELOC_16C_DISP04_C},
54   {R_16C_DISP08,    BFD_RELOC_16C_DISP08},
55   {R_16C_DISP08_C,  BFD_RELOC_16C_DISP08_C},
56   {R_16C_DISP16,    BFD_RELOC_16C_DISP16},
57   {R_16C_DISP16_C,  BFD_RELOC_16C_DISP16_C},
58   {R_16C_DISP24,    BFD_RELOC_16C_DISP24},
59   {R_16C_DISP24_C,  BFD_RELOC_16C_DISP24_C},
60   {R_16C_DISP24a,   BFD_RELOC_16C_DISP24a},
61   {R_16C_DISP24a_C, BFD_RELOC_16C_DISP24a_C},
62   {R_16C_REG04,     BFD_RELOC_16C_REG04},
63   {R_16C_REG04_C,   BFD_RELOC_16C_REG04_C},
64   {R_16C_REG04a,    BFD_RELOC_16C_REG04a},
65   {R_16C_REG04a_C,  BFD_RELOC_16C_REG04a_C},
66   {R_16C_REG14,     BFD_RELOC_16C_REG14},
67   {R_16C_REG14_C,   BFD_RELOC_16C_REG14_C},
68   {R_16C_REG16,     BFD_RELOC_16C_REG16},
69   {R_16C_REG16_C,   BFD_RELOC_16C_REG16_C},
70   {R_16C_REG20,     BFD_RELOC_16C_REG20},
71   {R_16C_REG20_C,   BFD_RELOC_16C_REG20_C},
72   {R_16C_ABS20,     BFD_RELOC_16C_ABS20},
73   {R_16C_ABS20_C,   BFD_RELOC_16C_ABS20_C},
74   {R_16C_ABS24,     BFD_RELOC_16C_ABS24},
75   {R_16C_ABS24_C,   BFD_RELOC_16C_ABS24_C},
76   {R_16C_IMM04,     BFD_RELOC_16C_IMM04},
77   {R_16C_IMM04_C,   BFD_RELOC_16C_IMM04_C},
78   {R_16C_IMM16,     BFD_RELOC_16C_IMM16},
79   {R_16C_IMM16_C,   BFD_RELOC_16C_IMM16_C},
80   {R_16C_IMM20,     BFD_RELOC_16C_IMM20},
81   {R_16C_IMM20_C,   BFD_RELOC_16C_IMM20_C},
82   {R_16C_IMM24,     BFD_RELOC_16C_IMM24},
83   {R_16C_IMM24_C,   BFD_RELOC_16C_IMM24_C},
84   {R_16C_IMM32,     BFD_RELOC_16C_IMM32},
85   {R_16C_IMM32_C,   BFD_RELOC_16C_IMM32_C}
86 };
87 
88 static reloc_howto_type elf_howto_table[] =
89 {
90   /* 00 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08),
91   /* 01 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08_C),
92   /* 02 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16),
93   /* 03 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16_C),
94   /* 04 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32),
95   /* 05 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32_C),
96   /* 06 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04),
97   /* 07 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04_C),
98   /* 08 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08),
99   /* 09 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08_C),
100   /* 10 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16),
101   /* 11 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16_C),
102   /* 12 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24),
103   /* 13 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24_C),
104   /* 14 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a),
105   /* 15 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a_C),
106   /* 16 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04),
107   /* 17 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04_C),
108   /* 18 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a),
109   /* 19 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a_C),
110   /* 20 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14),
111   /* 21 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14_C),
112   /* 22 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16),
113   /* 23 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16_C),
114   /* 24 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20),
115   /* 25 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20_C),
116   /* 26 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20),
117   /* 27 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20_C),
118   /* 28 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24),
119   /* 29 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24_C),
120   /* 30 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04),
121   /* 31 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04_C),
122   /* 32 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16),
123   /* 33 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16_C),
124   /* 34 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20),
125   /* 35 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20_C),
126   /* 36 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24),
127   /* 37 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24_C),
128   /* 38 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32),
129   /* 39 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32_C)
130 };
131 
132 
133 /* Code to turn a code_type into a howto ptr, uses the above howto table.  */
134 
135 static reloc_howto_type *
elf_cr16c_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)136 elf_cr16c_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
137 			     bfd_reloc_code_real_type code)
138 {
139   unsigned int i;
140 
141   for (i = 0; i < RINDEX_16C_MAX; i++)
142     {
143       if (code == reloc_map_index[i].bfd_reloc_enum)
144 	{
145 	  /* printf ("CR16C Relocation Type is - %x\n", code); */
146 	  return & elf_howto_table[i];
147 	}
148     }
149 
150   /* printf ("This relocation Type is not supported - %x\n", code); */
151   return 0;
152 }
153 
154 static reloc_howto_type *
elf_cr16c_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)155 elf_cr16c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
156 			     const char *r_name)
157 {
158   unsigned int i;
159 
160   for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
161     if (elf_howto_table[i].name != NULL
162 	&& strcasecmp (elf_howto_table[i].name, r_name) == 0)
163       return &elf_howto_table[i];
164 
165   return NULL;
166 }
167 
168 static void
elf_cr16c_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr ATTRIBUTE_UNUSED,Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)169 elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
170 			 arelent *cache_ptr ATTRIBUTE_UNUSED,
171 			 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
172 {
173   abort ();
174 }
175 
176 static void
elf_cr16c_info_to_howto_rel(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)177 elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
178 			     arelent *cache_ptr,
179 			     Elf_Internal_Rela *dst)
180 {
181   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
182 
183   if (r_type >= RINDEX_16C_MAX)
184     {
185       _bfd_error_handler (_("%B: invalid CR16C reloc number: %d"), abfd, r_type);
186       r_type = 0;
187     }
188   cache_ptr->howto = &elf_howto_table[r_type];
189 }
190 
191 /* Perform a relocation as part of a final link.  */
192 
193 static bfd_reloc_status_type
cr16c_elf_final_link_relocate(reloc_howto_type * howto,bfd * abfd,bfd * output_bfd ATTRIBUTE_UNUSED,asection * input_section,bfd_byte * data,bfd_vma octets,bfd_vma Rvalue,bfd_vma addend ATTRIBUTE_UNUSED,struct bfd_link_info * info ATTRIBUTE_UNUSED,asection * sym_sec ATTRIBUTE_UNUSED,int is_local ATTRIBUTE_UNUSED)194 cr16c_elf_final_link_relocate (reloc_howto_type *howto,
195 			       bfd *abfd,
196 			       bfd *output_bfd ATTRIBUTE_UNUSED,
197 			       asection *input_section,
198 			       bfd_byte *data,
199 			       bfd_vma octets,
200 			       bfd_vma Rvalue,
201 			       bfd_vma addend ATTRIBUTE_UNUSED,
202 			       struct bfd_link_info *info ATTRIBUTE_UNUSED,
203 			       asection *sym_sec ATTRIBUTE_UNUSED,
204 			       int is_local ATTRIBUTE_UNUSED)
205 {
206   long value;
207   short sword;			/* Extracted from the hole and put back.  */
208   unsigned long format, addr_type, code_factor;
209   unsigned short size;
210   unsigned short r_type;
211 
212   unsigned long disp20_opcod;
213   char neg = 0;
214   char neg2pos = 0;
215 
216   long left_val = 0;
217   long plus_factor = 0;		/* To be added to the hole.  */
218 
219 #define MIN_BYTE	((int) 0xFFFFFF80)
220 #define MIN_WORD	((int) 0xFFFF8000)
221 #define	MAX_UWORD	((unsigned) 0x0000FFFF)
222 #define	MAX_UBYTE	((unsigned) 0x000000FF)
223 
224   r_type = reloc_map_index[howto->type].cr_reloc_type;
225   format = r_type & R_FORMAT;
226   size = r_type & R_SIZESP;
227   addr_type = r_type & R_ADDRTYPE;
228   code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
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 
676 static bfd_boolean
elf32_cr16c_relocate_section(bfd * output_bfd,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)677 elf32_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, ignored;
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, ignored);
727 	}
728 
729       if (sec != NULL && discarded_section (sec))
730 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
731 					 rel, 1, relend, howto, 0, contents);
732 
733       if (bfd_link_relocatable (info))
734 	{
735 	  /* This is a relocatable link.  We don't have to change
736 	     anything, unless the reloc is against a section symbol,
737 	     in which case we have to adjust according to where the
738 	     section symbol winds up in the output section.  */
739 	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
740 	    rel->r_addend += sec->output_offset;
741 	  continue;
742 	}
743 
744       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
745 					 input_section,
746 					 contents, rel->r_offset,
747 					 relocation, rel->r_addend,
748 					 info, sec, h == NULL);
749 
750       if (r != bfd_reloc_ok)
751 	{
752 	  const char *name;
753 	  const char *msg = (const char *) 0;
754 
755 	  if (h != NULL)
756 	    name = h->root.root.string;
757 	  else
758 	    {
759 	      name = (bfd_elf_string_from_elf_section
760 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
761 	      if (name == NULL || *name == '\0')
762 		name = bfd_section_name (input_bfd, sec);
763 	    }
764 
765 	  switch (r)
766 	    {
767 	    case bfd_reloc_overflow:
768 	      (*info->callbacks->reloc_overflow)
769 		(info, (h ? &h->root : NULL), name, howto->name,
770 		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
771 	      break;
772 
773 	    case bfd_reloc_undefined:
774 	      (*info->callbacks->undefined_symbol)
775 		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
776 	      break;
777 
778 	    case bfd_reloc_outofrange:
779 	      msg = _("internal error: out of range error");
780 	      goto common_error;
781 
782 	    case bfd_reloc_notsupported:
783 	      msg = _("internal error: unsupported relocation error");
784 	      goto common_error;
785 
786 	    case bfd_reloc_dangerous:
787 	      msg = _("internal error: dangerous error");
788 	      goto common_error;
789 
790 	    default:
791 	      msg = _("internal error: unknown error");
792 	      /* fall through */
793 
794 	    common_error:
795 	      (*info->callbacks->warning) (info, msg, name, input_bfd,
796 					   input_section, rel->r_offset);
797 	      break;
798 	    }
799 	}
800     }
801 
802   return TRUE;
803 }
804 
805 /* CR16C ELF uses three common sections:
806    One is for default common symbols (placed in usual common section).
807    Second is for near common symbols (placed in "ncommon" section).
808    Third is for far common symbols (placed in "fcommon" section).
809    The following implementation is based on elf32-mips architecture */
810 
811 static asection  cr16c_elf_fcom_section;
812 static asymbol   cr16c_elf_fcom_symbol;
813 static asymbol * cr16c_elf_fcom_symbol_ptr;
814 static asection  cr16c_elf_ncom_section;
815 static asymbol   cr16c_elf_ncom_symbol;
816 static asymbol * cr16c_elf_ncom_symbol_ptr;
817 
818 /* Given a BFD section, try to locate the
819    corresponding ELF section index.  */
820 
821 static bfd_boolean
elf32_cr16c_section_from_bfd_section(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,int * retval)822 elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
823 				      asection *sec,
824 				      int *retval)
825 {
826   if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
827     *retval = SHN_CR16C_FCOMMON;
828   else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
829     *retval = SHN_CR16C_NCOMMON;
830   else
831     return FALSE;
832 
833   return TRUE;
834 }
835 
836 /* Handle the special CR16C section numbers that a symbol may use.  */
837 
838 static void
elf32_cr16c_symbol_processing(bfd * abfd ATTRIBUTE_UNUSED,asymbol * asym)839 elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
840 			       asymbol *asym)
841 {
842   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
843   unsigned int indx;
844 
845   indx = elfsym->internal_elf_sym.st_shndx;
846 
847   switch (indx)
848     {
849     case SHN_CR16C_FCOMMON:
850       if (cr16c_elf_fcom_section.name == NULL)
851 	{
852 	  /* Initialize the far common section.  */
853 	  cr16c_elf_fcom_section.name = ".fcommon";
854 	  cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
855 	  cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
856 	  cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
857 	  cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
858 	  cr16c_elf_fcom_symbol.name = ".fcommon";
859 	  cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
860 	  cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
861 	  cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
862 	}
863       asym->section = &cr16c_elf_fcom_section;
864       asym->value = elfsym->internal_elf_sym.st_size;
865       break;
866     case SHN_CR16C_NCOMMON:
867       if (cr16c_elf_ncom_section.name == NULL)
868 	{
869 	  /* Initialize the far common section.  */
870 	  cr16c_elf_ncom_section.name = ".ncommon";
871 	  cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
872 	  cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
873 	  cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
874 	  cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
875 	  cr16c_elf_ncom_symbol.name = ".ncommon";
876 	  cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
877 	  cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
878 	  cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
879 	}
880       asym->section = &cr16c_elf_ncom_section;
881       asym->value = elfsym->internal_elf_sym.st_size;
882       break;
883     }
884 }
885 
886 /* Hook called by the linker routine which adds symbols from an object
887    file.  We must handle the special cr16c section numbers here.  */
888 
889 static bfd_boolean
elf32_cr16c_add_symbol_hook(bfd * abfd,struct bfd_link_info * info ATTRIBUTE_UNUSED,Elf_Internal_Sym * sym,const char ** namep ATTRIBUTE_UNUSED,flagword * flagsp ATTRIBUTE_UNUSED,asection ** secp,bfd_vma * valp)890 elf32_cr16c_add_symbol_hook (bfd *abfd,
891 			     struct bfd_link_info *info ATTRIBUTE_UNUSED,
892 			     Elf_Internal_Sym *sym,
893 			     const char **namep ATTRIBUTE_UNUSED,
894 			     flagword *flagsp ATTRIBUTE_UNUSED,
895 			     asection **secp,
896 			     bfd_vma *valp)
897 {
898   unsigned int indx = sym->st_shndx;
899 
900   switch (indx)
901     {
902     case SHN_CR16C_FCOMMON:
903       *secp = bfd_make_section_old_way (abfd, ".fcommon");
904       (*secp)->flags |= SEC_IS_COMMON;
905       *valp = sym->st_size;
906       break;
907     case SHN_CR16C_NCOMMON:
908       *secp = bfd_make_section_old_way (abfd, ".ncommon");
909       (*secp)->flags |= SEC_IS_COMMON;
910       *valp = sym->st_size;
911       break;
912     }
913 
914   return TRUE;
915 }
916 
917 static int
elf32_cr16c_link_output_symbol_hook(struct bfd_link_info * info ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED,Elf_Internal_Sym * sym,asection * input_sec,struct elf_link_hash_entry * h ATTRIBUTE_UNUSED)918 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
919 				     const char *name ATTRIBUTE_UNUSED,
920 				     Elf_Internal_Sym *sym,
921 				     asection *input_sec,
922 				     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
923 {
924   /* If we see a common symbol, which implies a relocatable link, then
925      if a symbol was in a special common section in an input file, mark
926      it as a special common in the output file.  */
927 
928   if (sym->st_shndx == SHN_COMMON)
929     {
930       if (strcmp (input_sec->name, ".fcommon") == 0)
931 	sym->st_shndx = SHN_CR16C_FCOMMON;
932       else if (strcmp (input_sec->name, ".ncommon") == 0)
933 	sym->st_shndx = SHN_CR16C_NCOMMON;
934     }
935 
936   return 1;
937 }
938 
939 /* Definitions for setting CR16C target vector.  */
940 #define TARGET_LITTLE_SYM		cr16c_elf32_vec
941 #define TARGET_LITTLE_NAME		"elf32-cr16c"
942 #define ELF_ARCH			bfd_arch_cr16c
943 #define ELF_MACHINE_CODE		EM_CR
944 #define ELF_MAXPAGESIZE			0x1
945 #define elf_symbol_leading_char		'_'
946 
947 #define bfd_elf32_bfd_reloc_type_lookup		elf_cr16c_reloc_type_lookup
948 #define bfd_elf32_bfd_reloc_name_lookup	elf_cr16c_reloc_name_lookup
949 #define elf_info_to_howto			elf_cr16c_info_to_howto
950 #define elf_info_to_howto_rel			elf_cr16c_info_to_howto_rel
951 #define elf_backend_relocate_section		elf32_cr16c_relocate_section
952 #define elf_backend_symbol_processing		elf32_cr16c_symbol_processing
953 #define elf_backend_section_from_bfd_section 	elf32_cr16c_section_from_bfd_section
954 #define elf_backend_add_symbol_hook		elf32_cr16c_add_symbol_hook
955 #define elf_backend_link_output_symbol_hook 	elf32_cr16c_link_output_symbol_hook
956 
957 #define elf_backend_can_gc_sections     1
958 
959 #include "elf32-target.h"
960