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