ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / bfd / elf32-cr16c.c
CommitLineData
0949843d 1/* BFD back-end for National Semiconductor's CR16C ELF
b90efa5b 2 Copyright (C) 2004-2015 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
0949843d
NC
168static void
169elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
170 arelent *cache_ptr ATTRIBUTE_UNUSED,
171 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
172{
173 abort ();
174}
175
176static void
177elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
178 arelent *cache_ptr,
179 Elf_Internal_Rela *dst)
180{
181 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
182
5860e3f8
NC
183 if (r_type >= RINDEX_16C_MAX)
184 {
185 _bfd_error_handler (_("%A; invalid CR16C reloc number: %d"), abfd, r_type);
186 r_type = 0;
187 }
0949843d
NC
188 cache_ptr->howto = &elf_howto_table[r_type];
189}
190
191/* Perform a relocation as part of a final link. */
192
193static bfd_reloc_status_type
194cr16c_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;
0949843d
NC
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
0949843d
NC
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);
0949843d 444 break;
90e868ac 445
0949843d
NC
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);
0949843d 453 break;
90e868ac 454
0949843d
NC
455 case R_S_16C_32: /* Four bytes. */
456 value &= 0xFFFFFFFF;
457 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
0949843d 458 break;
90e868ac 459
0949843d
NC
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);
0949843d 477 break;
90e868ac 478
0949843d
NC
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);
0949843d 489 break;
90e868ac 490
0949843d
NC
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);
0949843d 500 break;
90e868ac 501
0949843d
NC
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);
0949843d 511 break;
90e868ac 512
0949843d
NC
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);
0949843d 525 break;
90e868ac 526
0949843d
NC
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);
0949843d 541 break;
90e868ac 542
0949843d
NC
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);
0949843d 550 break;
90e868ac 551
0949843d
NC
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);
0949843d 561 break;
90e868ac 562
0949843d
NC
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);
0949843d 570 break;
90e868ac 571
0949843d
NC
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 }
0949843d 591 break;
90e868ac 592
0949843d
NC
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);
0949843d 609 break;
90e868ac 610
0949843d
NC
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);
0949843d 618 break;
90e868ac 619
0949843d
NC
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);
0949843d 635 break;
90e868ac 636
0949843d
NC
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);
0949843d 644 break;
90e868ac 645
0949843d
NC
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);
0949843d 654 break;
90e868ac 655
0949843d
NC
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);
0949843d 661 break;
90e868ac 662
0949843d
NC
663 default:
664 return bfd_reloc_notsupported;
665 }
666 break;
667 default:
668 return bfd_reloc_notsupported;
669 }
90e868ac
NC
670
671 return bfd_reloc_ok;
0949843d
NC
672}
673
674/* Relocate a CR16C ELF section. */
675
676static bfd_boolean
677elf32_cr16c_relocate_section (bfd *output_bfd,
678 struct bfd_link_info *info,
679 bfd *input_bfd,
680 asection *input_section,
681 bfd_byte *contents,
682 Elf_Internal_Rela *relocs,
683 Elf_Internal_Sym *local_syms,
684 asection **local_sections)
685{
686 Elf_Internal_Shdr *symtab_hdr;
687 struct elf_link_hash_entry **sym_hashes;
688 Elf_Internal_Rela *rel, *relend;
689
690 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
691 sym_hashes = elf_sym_hashes (input_bfd);
692
693 rel = relocs;
694 relend = relocs + input_section->reloc_count;
695 for (; rel < relend; rel++)
696 {
697 int r_type;
698 reloc_howto_type *howto;
699 unsigned long r_symndx;
700 Elf_Internal_Sym *sym;
701 asection *sec;
702 struct elf_link_hash_entry *h;
703 bfd_vma relocation;
704 bfd_reloc_status_type r;
705
706 r_symndx = ELF32_R_SYM (rel->r_info);
707 r_type = ELF32_R_TYPE (rel->r_info);
708 howto = elf_howto_table + r_type;
709
0949843d
NC
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 {
62d887d4 721 bfd_boolean unresolved_reloc, warned, ignored;
a4d7b4b5
L
722
723 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
724 r_symndx, symtab_hdr, sym_hashes,
725 h, sec, relocation,
62d887d4 726 unresolved_reloc, warned, ignored);
0949843d
NC
727 }
728
dbaa2011 729 if (sec != NULL && discarded_section (sec))
e4067dbb 730 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 731 rel, 1, relend, howto, 0, contents);
ab96bf03
AM
732
733 if (info->relocatable)
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
0949843d
NC
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 if (!((*info->callbacks->reloc_overflow)
dfeffb9f
L
769 (info, (h ? &h->root : NULL), name, howto->name,
770 (bfd_vma) 0, input_bfd, input_section,
771 rel->r_offset)))
0949843d
NC
772 return FALSE;
773 break;
774
775 case bfd_reloc_undefined:
776 if (!((*info->callbacks->undefined_symbol)
777 (info, name, input_bfd, input_section,
778 rel->r_offset, TRUE)))
779 return FALSE;
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:
799 if (!((*info->callbacks->warning)
800 (info, msg, name, input_bfd, input_section,
801 rel->r_offset)))
802 return FALSE;
803 break;
804 }
805 }
806 }
807
808 return TRUE;
809}
810
0949843d
NC
811/* CR16C ELF uses three common sections:
812 One is for default common symbols (placed in usual common section).
813 Second is for near common symbols (placed in "ncommon" section).
814 Third is for far common symbols (placed in "fcommon" section).
815 The following implementation is based on elf32-mips architecture */
816
817static asection cr16c_elf_fcom_section;
818static asymbol cr16c_elf_fcom_symbol;
819static asymbol * cr16c_elf_fcom_symbol_ptr;
820static asection cr16c_elf_ncom_section;
821static asymbol cr16c_elf_ncom_symbol;
822static asymbol * cr16c_elf_ncom_symbol_ptr;
823
824/* Given a BFD section, try to locate the
825 corresponding ELF section index. */
826
827static bfd_boolean
828elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
829 asection *sec,
830 int *retval)
831{
832 if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
833 *retval = SHN_CR16C_FCOMMON;
834 else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
835 *retval = SHN_CR16C_NCOMMON;
836 else
837 return FALSE;
838
839 return TRUE;
840}
841
842/* Handle the special CR16C section numbers that a symbol may use. */
843
844static void
845elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
846 asymbol *asym)
847{
848 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
849 unsigned int indx;
850
851 indx = elfsym->internal_elf_sym.st_shndx;
852
853 switch (indx)
854 {
855 case SHN_CR16C_FCOMMON:
856 if (cr16c_elf_fcom_section.name == NULL)
857 {
858 /* Initialize the far common section. */
859 cr16c_elf_fcom_section.name = ".fcommon";
860 cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
861 cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
862 cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
863 cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
864 cr16c_elf_fcom_symbol.name = ".fcommon";
865 cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
866 cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
867 cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
868 }
869 asym->section = &cr16c_elf_fcom_section;
870 asym->value = elfsym->internal_elf_sym.st_size;
871 break;
872 case SHN_CR16C_NCOMMON:
873 if (cr16c_elf_ncom_section.name == NULL)
874 {
875 /* Initialize the far common section. */
876 cr16c_elf_ncom_section.name = ".ncommon";
877 cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
878 cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
879 cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
880 cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
881 cr16c_elf_ncom_symbol.name = ".ncommon";
882 cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
883 cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
884 cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
885 }
886 asym->section = &cr16c_elf_ncom_section;
887 asym->value = elfsym->internal_elf_sym.st_size;
888 break;
889 }
890}
891
892/* Hook called by the linker routine which adds symbols from an object
893 file. We must handle the special cr16c section numbers here. */
894
895static bfd_boolean
896elf32_cr16c_add_symbol_hook (bfd *abfd,
897 struct bfd_link_info *info ATTRIBUTE_UNUSED,
a4d7b4b5 898 Elf_Internal_Sym *sym,
0949843d
NC
899 const char **namep ATTRIBUTE_UNUSED,
900 flagword *flagsp ATTRIBUTE_UNUSED,
901 asection **secp,
902 bfd_vma *valp)
903{
904 unsigned int indx = sym->st_shndx;
905
906 switch (indx)
907 {
908 case SHN_CR16C_FCOMMON:
909 *secp = bfd_make_section_old_way (abfd, ".fcommon");
910 (*secp)->flags |= SEC_IS_COMMON;
911 *valp = sym->st_size;
912 break;
913 case SHN_CR16C_NCOMMON:
914 *secp = bfd_make_section_old_way (abfd, ".ncommon");
915 (*secp)->flags |= SEC_IS_COMMON;
916 *valp = sym->st_size;
917 break;
918 }
919
920 return TRUE;
921}
922
6e0b88f1 923static int
0949843d
NC
924elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
925 const char *name ATTRIBUTE_UNUSED,
926 Elf_Internal_Sym *sym,
927 asection *input_sec,
928 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
929{
930 /* If we see a common symbol, which implies a relocatable link, then
931 if a symbol was in a special common section in an input file, mark
932 it as a special common in the output file. */
933
934 if (sym->st_shndx == SHN_COMMON)
935 {
936 if (strcmp (input_sec->name, ".fcommon") == 0)
937 sym->st_shndx = SHN_CR16C_FCOMMON;
938 else if (strcmp (input_sec->name, ".ncommon") == 0)
939 sym->st_shndx = SHN_CR16C_NCOMMON;
940 }
941
6e0b88f1 942 return 1;
0949843d
NC
943}
944
945/* Definitions for setting CR16C target vector. */
6d00b590 946#define TARGET_LITTLE_SYM cr16c_elf32_vec
0949843d
NC
947#define TARGET_LITTLE_NAME "elf32-cr16c"
948#define ELF_ARCH bfd_arch_cr16c
949#define ELF_MACHINE_CODE EM_CR
950#define ELF_MAXPAGESIZE 0x1
951#define elf_symbol_leading_char '_'
952
953#define bfd_elf32_bfd_reloc_type_lookup elf_cr16c_reloc_type_lookup
157090f7 954#define bfd_elf32_bfd_reloc_name_lookup elf_cr16c_reloc_name_lookup
0949843d
NC
955#define elf_info_to_howto elf_cr16c_info_to_howto
956#define elf_info_to_howto_rel elf_cr16c_info_to_howto_rel
957#define elf_backend_relocate_section elf32_cr16c_relocate_section
0949843d
NC
958#define elf_backend_symbol_processing elf32_cr16c_symbol_processing
959#define elf_backend_section_from_bfd_section elf32_cr16c_section_from_bfd_section
960#define elf_backend_add_symbol_hook elf32_cr16c_add_symbol_hook
961#define elf_backend_link_output_symbol_hook elf32_cr16c_link_output_symbol_hook
962
963#define elf_backend_can_gc_sections 1
964
965#include "elf32-target.h"
This page took 0.531066 seconds and 4 git commands to generate.