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