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