1 /* BFD back-end for National Semiconductor's CR16C ELF
2 Copyright (C) 2004-2017 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
25 #include "elf/cr16c.h"
29 #define USE_REL 1 /* CR16C uses REL relocations instead of RELA. */
31 /* The following definition is based on EMPTY_HOWTO macro,
32 but also initiates the "name" field in HOWTO struct. */
33 #define ONLY_NAME_HOWTO(C) \
34 HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
35 STRINGX(C), FALSE, 0, 0, FALSE)
37 /* reloc_map_index array maps CRASM relocation type into a BFD
38 relocation enum. The array's indices are synchronized with
39 RINDEX_16C_* indices, created in include/elf/cr16c.h.
41 1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup().
42 2. asreloc.c : find_reloc_type(). */
44 RELOC_MAP reloc_map_index
[RINDEX_16C_MAX
] =
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
}
88 static reloc_howto_type elf_howto_table
[] =
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
)
133 /* Code to turn a code_type into a howto ptr, uses the above howto table. */
135 static reloc_howto_type
*
136 elf_cr16c_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
137 bfd_reloc_code_real_type code
)
141 for (i
= 0; i
< RINDEX_16C_MAX
; i
++)
143 if (code
== reloc_map_index
[i
].bfd_reloc_enum
)
145 /* printf ("CR16C Relocation Type is - %x\n", code); */
146 return & elf_howto_table
[i
];
150 /* printf ("This relocation Type is not supported - %x\n", code); */
154 static reloc_howto_type
*
155 elf_cr16c_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
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
];
169 elf_cr16c_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
170 arelent
*cache_ptr ATTRIBUTE_UNUSED
,
171 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
)
177 elf_cr16c_info_to_howto_rel (bfd
*abfd ATTRIBUTE_UNUSED
,
179 Elf_Internal_Rela
*dst
)
181 unsigned int r_type
= ELF32_R_TYPE (dst
->r_info
);
183 if (r_type
>= RINDEX_16C_MAX
)
185 /* xgettext:c-format */
186 _bfd_error_handler (_("%B: invalid CR16C reloc number: %d"), abfd
, r_type
);
189 cache_ptr
->howto
= &elf_howto_table
[r_type
];
192 /* Perform a relocation as part of a final link. */
194 static bfd_reloc_status_type
195 cr16c_elf_final_link_relocate (reloc_howto_type
*howto
,
197 bfd
*output_bfd ATTRIBUTE_UNUSED
,
198 asection
*input_section
,
202 bfd_vma addend ATTRIBUTE_UNUSED
,
203 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
204 asection
*sym_sec ATTRIBUTE_UNUSED
,
205 int is_local ATTRIBUTE_UNUSED
)
208 short sword
; /* Extracted from the hole and put back. */
209 unsigned long format
, addr_type
, code_factor
;
211 unsigned short r_type
;
213 unsigned long disp20_opcod
;
218 long plus_factor
= 0; /* To be added to the hole. */
220 #define MIN_BYTE ((int) 0xFFFFFF80)
221 #define MIN_WORD ((int) 0xFFFF8000)
222 #define MAX_UWORD ((unsigned) 0x0000FFFF)
223 #define MAX_UBYTE ((unsigned) 0x000000FF)
225 r_type
= reloc_map_index
[howto
->type
].cr_reloc_type
;
226 format
= r_type
& R_FORMAT
;
227 size
= r_type
& R_SIZESP
;
228 addr_type
= r_type
& R_ADDRTYPE
;
229 code_factor
= ((addr_type
== R_CODE_ADDR
) ? 1 : 0);
236 case R_S_16C_08
: /* One byte. */
237 value
= bfd_get_8 (abfd
, (char *) data
+ octets
);
239 case R_S_16C_16
: /* Two bytes. */
240 sword
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ octets
);
243 case R_S_16C_32
: /* Four bytes. */
244 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
247 return bfd_reloc_notsupported
;
254 case R_S_16C_04
: /* word1(4-7). */
255 value
= bfd_get_8 (abfd
, (char *) data
+ octets
);
256 left_val
= value
& 0xF;
257 value
= (value
& 0xF0) >> 4;
261 case R_S_16C_08
: /* word1(0-3,8-11). */
262 sword
= bfd_get_16 (abfd
, (char *) data
+ octets
);
263 value
= sword
& 0x000F;
264 value
|= ((sword
& 0x0F00) >> 4);
265 left_val
= sword
& 0xF0F0;
270 case R_S_16C_16
: /* word2. */
271 sword
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ octets
);
273 value
= ((value
& 0xFFFE) >> 1) | ((value
& 0x1) << 15);
278 case R_S_16C_24_a
: /* word1(0-7),word2. */
279 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
280 left_val
= value
& 0x0000FF00;
281 value
= ((value
& 0xFFFE0000) >> 17) |
282 ((value
& 0x00010000) << 7) | ((value
& 0x000000FF) << 15);
284 if (value
& 0x1000000)
287 case R_S_16C_24
: /* word2(0-3,8-11),word3. */
288 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
289 left_val
= value
& 0x0000F0F0;
290 value
= ((value
>> 16) & 0x0000FFFF) |
291 ((value
& 0x00000F00) << 8) | ((value
& 0x0000000F) << 20);
293 value
= ((value
& 0x00FFFFFE) >> 1) | ((value
& 0x00000001) << 23);
296 if (value
& 0x1000000)
300 return bfd_reloc_notsupported
;
307 case R_S_16C_04
: /* word1(12-15) not scaled. */
308 value
= bfd_get_8 (abfd
, (char *) data
+ octets
);
309 left_val
= value
& 0xF0;
312 case R_S_16C_04_a
: /* word1(12-15) scaled by 2. */
313 value
= bfd_get_8 (abfd
, (char *) data
+ octets
);
314 left_val
= value
& 0xF0;
318 case R_S_16C_14
: /* word1(4-5),word2(0-3,8-15). */
319 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
320 left_val
= value
& 0x00F0FFCF;
321 value
= ((value
& 0xc0000000) >> 24) |
322 ((value
& 0x3F000000) >> 16) |
323 ((value
& 0x000F0000) >> 16) | (value
& 0x00000030);
325 case R_S_16C_16
: /* word2. */
326 sword
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ octets
);
329 case R_S_16C_20
: /* word2(8-11),word3. */
330 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
331 left_val
= value
& 0xF0;
332 value
= (value
& 0xF) << 16;
333 sword
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ octets
+ 1);
334 value
= value
| (unsigned short) sword
;
335 disp20_opcod
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
- 3);
336 disp20_opcod
|= 0x0FFF0000;
337 if ((disp20_opcod
== 0x4FFF0018) || /* loadb -disp20(reg) */
338 (disp20_opcod
== 0x5FFF0018) || /* loadb -disp20(rp) */
339 (disp20_opcod
== 0x8FFF0018) || /* loadd -disp20(reg) */
340 (disp20_opcod
== 0x9FFF0018) || /* loadd -disp20(rp) */
341 (disp20_opcod
== 0xCFFF0018) || /* loadw -disp20(reg) */
342 (disp20_opcod
== 0xDFFF0018) || /* loadw -disp20(rp) */
343 (disp20_opcod
== 0x4FFF0019) || /* storb -disp20(reg) */
344 (disp20_opcod
== 0x5FFF0019) || /* storb -disp20(rp) */
345 (disp20_opcod
== 0x8FFF0019) || /* stord -disp20(reg) */
346 (disp20_opcod
== 0x9FFF0019) || /* stord -disp20(rp) */
347 (disp20_opcod
== 0xCFFF0019) || /* storw -disp20(reg) */
348 (disp20_opcod
== 0xDFFF0019))
349 { /* storw -disp20(rp). */
356 return bfd_reloc_notsupported
;
363 case R_S_16C_20
: /* word1(0-3),word2. */
364 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
365 left_val
= value
& 0x0000FFF0;
366 value
= ((value
& 0xFFFF0000) >> 16) |
367 ((value
& 0x0000000F) << 16);
369 case R_S_16C_24
: /* word2(0-3,8-11),word3. */
370 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
371 left_val
= value
& 0x0000F0F0;
372 value
= ((value
& 0xFFFF0000) >> 16) |
373 ((value
& 0x00000F00) << 8) | ((value
& 0x0000000F) << 20);
376 return bfd_reloc_notsupported
;
383 case R_S_16C_04
: /* word1/2(4-7). */
384 value
= bfd_get_8 (abfd
, (char *) data
+ octets
);
385 left_val
= value
& 0xF;
386 value
= (value
& 0xF0) >> 4;
388 case R_S_16C_16
: /* word2. */
389 sword
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ octets
);
392 case R_S_16C_20
: /* word1(0-3),word2. */
393 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
394 left_val
= value
& 0x0000FFF0;
395 value
= ((value
& 0xFFFF0000) >> 16) |
396 ((value
& 0x0000000F) << 16);
398 case R_S_16C_32
: /* word2, word3. */
399 value
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ octets
);
400 value
= ((value
& 0x0000FFFF) << 16) |
401 ((value
& 0xFFFF0000) >> 16);
404 return bfd_reloc_notsupported
;
408 return bfd_reloc_notsupported
;
411 switch ((r_type
& R_RELTO
) >> 4)
415 plus_factor
= Rvalue
;
417 case 1: /* R_PCREL. */
418 plus_factor
= Rvalue
-
419 (input_section
->output_section
->vma
+ input_section
->output_offset
);
422 return bfd_reloc_notsupported
;
427 if (plus_factor
>= -value
)
429 /* We need to change load/stor with negative
430 displ opcode to positive disp opcode (CR16C). */
433 value
= value
+ (plus_factor
>> code_factor
);
440 case R_S_16C_08
: /* One byte. */
441 if (value
> (int) MAX_UBYTE
|| value
< MIN_BYTE
)
442 return bfd_reloc_overflow
;
444 bfd_put_8 (abfd
, (bfd_vma
) value
, (unsigned char *) data
+ octets
);
447 case R_S_16C_16
: /* Two bytes. */
448 if (value
> (int) MAX_UWORD
|| value
< MIN_WORD
)
449 return bfd_reloc_overflow
;
452 bfd_put_16 (abfd
, (bfd_vma
) sword
,
453 (unsigned char *) data
+ octets
);
456 case R_S_16C_32
: /* Four bytes. */
458 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
462 return bfd_reloc_notsupported
;
469 case R_S_16C_04
: /* word1(4-7). */
470 if ((value
- 32) > 32 || value
< 2)
471 return bfd_reloc_overflow
;
477 bfd_put_8 (abfd
, (bfd_vma
) value
, (unsigned char *) data
+ octets
);
480 case R_S_16C_08
: /* word1(0-3,8-11). */
481 if (value
> 255 || value
< -256 || value
== 0x80)
482 return bfd_reloc_overflow
;
485 sword
= value
& 0x000F;
486 sword
|= (value
& 0x00F0) << 4;
488 bfd_put_16 (abfd
, (bfd_vma
) sword
,
489 (unsigned char *) data
+ octets
);
492 case R_S_16C_16
: /* word2. */
493 if (value
> 65535 || value
< -65536)
494 return bfd_reloc_overflow
;
497 value
= ((value
& 0x8000) >> 15) | ((value
& 0x7FFF) << 1);
499 bfd_put_16 (abfd
, (bfd_vma
) sword
,
500 (unsigned char *) data
+ octets
);
503 case R_S_16C_24_a
: /* word1(0-7),word2. */
504 if (value
> 16777215 || value
< -16777216)
505 return bfd_reloc_overflow
;
508 value
= ((value
& 0x00007FFF) << 17) |
509 ((value
& 0x00800000) >> 7) | ((value
& 0x007F8000) >> 15);
511 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
514 case R_S_16C_24
: /* word2(0-3,8-11),word3. */
515 if (value
> 16777215 || value
< -16777216)
516 return bfd_reloc_overflow
;
520 value
= ((value
& 0x007FFFFF) << 1) | ((value
& 0x00800000) >> 23);
522 value
= ((value
& 0x0000FFFF) << 16) |
523 ((value
& 0x000F0000) >> 8) | ((value
& 0x00F00000) >> 20);
525 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
529 return bfd_reloc_notsupported
;
536 case R_S_16C_04
: /* word1(12-15) not scaled. */
537 if (value
> 13 || value
< 0)
538 return bfd_reloc_overflow
;
541 bfd_put_8 (abfd
, (bfd_vma
) value
, (unsigned char *) data
+ octets
);
544 case R_S_16C_04_a
: /* word1(12-15) not scaled. */
545 if (value
> 26 || value
< 0)
546 return bfd_reloc_overflow
;
550 bfd_put_8 (abfd
, (bfd_vma
) value
, (unsigned char *) data
+ octets
);
553 case R_S_16C_14
: /* word1(4-5),word2(0-3,8-15). */
554 if (value
< 0 || value
> 16383)
555 return bfd_reloc_overflow
;
557 value
= ((value
& 0x000000c0) << 24) |
558 ((value
& 0x00003F00) << 16) |
559 ((value
& 0x0000000F) << 16) | (value
& 0x00000030);
561 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
564 case R_S_16C_16
: /* word2. */
565 if (value
> 65535 || value
< 0)
566 return bfd_reloc_overflow
;
569 bfd_put_16 (abfd
, (bfd_vma
) sword
,
570 (unsigned char *) data
+ octets
);
573 case R_S_16C_20
: /* word2(8-11),word3. */
574 /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */
576 sword
= value
& 0x0000FFFF;
577 value
= (value
& 0x000F0000) >> 16;
579 bfd_put_8 (abfd
, (bfd_vma
) value
, (unsigned char *) data
+ octets
);
580 bfd_put_16 (abfd
, (bfd_vma
) sword
,
581 (unsigned char *) data
+ octets
+ 1);
584 /* Change load/stor negative displ opcode
585 to load/stor positive displ opcode. */
586 value
= bfd_get_8 (abfd
, (char *) data
+ octets
- 3);
589 bfd_put_8 (abfd
, (bfd_vma
) value
,
590 (unsigned char *) data
+ octets
- 3);
595 return bfd_reloc_notsupported
;
602 case R_S_16C_20
: /* word1(0-3),word2. */
603 if (value
> 1048575 || value
< 0)
604 return bfd_reloc_overflow
;
606 value
= ((value
& 0x0000FFFF) << 16) |
607 ((value
& 0x000F0000) >> 16);
609 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
612 case R_S_16C_24
: /* word2(0-3,8-11),word3. */
613 /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */
615 value
= ((value
& 0x0000FFFF) << 16) |
616 ((value
& 0x000F0000) >> 8) | ((value
& 0x00F00000) >> 20);
618 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
622 return bfd_reloc_notsupported
;
629 case R_S_16C_04
: /* word1/2(4-7). */
630 if (value
> 15 || value
< -1)
631 return bfd_reloc_overflow
;
635 bfd_put_8 (abfd
, (bfd_vma
) value
, (unsigned char *) data
+ octets
);
638 case R_S_16C_16
: /* word2. */
639 if (value
> 32767 || value
< -32768)
640 return bfd_reloc_overflow
;
643 bfd_put_16 (abfd
, (bfd_vma
) sword
,
644 (unsigned char *) data
+ octets
);
647 case R_S_16C_20
: /* word1(0-3),word2. */
648 if (value
> 1048575 || value
< 0)
649 return bfd_reloc_overflow
;
651 value
= ((value
& 0x0000FFFF) << 16) |
652 ((value
& 0x000F0000) >> 16);
654 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
657 case R_S_16C_32
: /* word2, word3. */
659 value
= ((value
& 0x0000FFFF) << 16) |
660 ((value
& 0xFFFF0000) >> 16);
661 bfd_put_32 (abfd
, (bfd_vma
) value
, (bfd_byte
*) data
+ octets
);
665 return bfd_reloc_notsupported
;
669 return bfd_reloc_notsupported
;
675 /* Relocate a CR16C ELF section. */
678 elf32_cr16c_relocate_section (bfd
*output_bfd
,
679 struct bfd_link_info
*info
,
681 asection
*input_section
,
683 Elf_Internal_Rela
*relocs
,
684 Elf_Internal_Sym
*local_syms
,
685 asection
**local_sections
)
687 Elf_Internal_Shdr
*symtab_hdr
;
688 struct elf_link_hash_entry
**sym_hashes
;
689 Elf_Internal_Rela
*rel
, *relend
;
691 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
692 sym_hashes
= elf_sym_hashes (input_bfd
);
695 relend
= relocs
+ input_section
->reloc_count
;
696 for (; rel
< relend
; rel
++)
699 reloc_howto_type
*howto
;
700 unsigned long r_symndx
;
701 Elf_Internal_Sym
*sym
;
703 struct elf_link_hash_entry
*h
;
705 bfd_reloc_status_type r
;
707 r_symndx
= ELF32_R_SYM (rel
->r_info
);
708 r_type
= ELF32_R_TYPE (rel
->r_info
);
709 howto
= elf_howto_table
+ r_type
;
714 if (r_symndx
< symtab_hdr
->sh_info
)
716 sym
= local_syms
+ r_symndx
;
717 sec
= local_sections
[r_symndx
];
718 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
722 bfd_boolean unresolved_reloc
, warned
, ignored
;
724 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
725 r_symndx
, symtab_hdr
, sym_hashes
,
727 unresolved_reloc
, warned
, ignored
);
730 if (sec
!= NULL
&& discarded_section (sec
))
731 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
732 rel
, 1, relend
, howto
, 0, contents
);
734 if (bfd_link_relocatable (info
))
736 /* This is a relocatable link. We don't have to change
737 anything, unless the reloc is against a section symbol,
738 in which case we have to adjust according to where the
739 section symbol winds up in the output section. */
740 if (sym
!= NULL
&& ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
741 rel
->r_addend
+= sec
->output_offset
;
745 r
= cr16c_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
747 contents
, rel
->r_offset
,
748 relocation
, rel
->r_addend
,
749 info
, sec
, h
== NULL
);
751 if (r
!= bfd_reloc_ok
)
754 const char *msg
= (const char *) 0;
757 name
= h
->root
.root
.string
;
760 name
= (bfd_elf_string_from_elf_section
761 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
762 if (name
== NULL
|| *name
== '\0')
763 name
= bfd_section_name (input_bfd
, sec
);
768 case bfd_reloc_overflow
:
769 (*info
->callbacks
->reloc_overflow
)
770 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
771 (bfd_vma
) 0, input_bfd
, input_section
, rel
->r_offset
);
774 case bfd_reloc_undefined
:
775 (*info
->callbacks
->undefined_symbol
)
776 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
);
779 case bfd_reloc_outofrange
:
780 msg
= _("internal error: out of range error");
783 case bfd_reloc_notsupported
:
784 msg
= _("internal error: unsupported relocation error");
787 case bfd_reloc_dangerous
:
788 msg
= _("internal error: dangerous error");
792 msg
= _("internal error: unknown error");
796 (*info
->callbacks
->warning
) (info
, msg
, name
, input_bfd
,
797 input_section
, rel
->r_offset
);
806 /* CR16C ELF uses three common sections:
807 One is for default common symbols (placed in usual common section).
808 Second is for near common symbols (placed in "ncommon" section).
809 Third is for far common symbols (placed in "fcommon" section).
810 The following implementation is based on elf32-mips architecture */
812 static asection cr16c_elf_fcom_section
;
813 static asymbol cr16c_elf_fcom_symbol
;
814 static asymbol
* cr16c_elf_fcom_symbol_ptr
;
815 static asection cr16c_elf_ncom_section
;
816 static asymbol cr16c_elf_ncom_symbol
;
817 static asymbol
* cr16c_elf_ncom_symbol_ptr
;
819 /* Given a BFD section, try to locate the
820 corresponding ELF section index. */
823 elf32_cr16c_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
827 if (strcmp (bfd_get_section_name (abfd
, sec
), ".fcommon") == 0)
828 *retval
= SHN_CR16C_FCOMMON
;
829 else if (strcmp (bfd_get_section_name (abfd
, sec
), ".ncommon") == 0)
830 *retval
= SHN_CR16C_NCOMMON
;
837 /* Handle the special CR16C section numbers that a symbol may use. */
840 elf32_cr16c_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
843 elf_symbol_type
*elfsym
= (elf_symbol_type
*) asym
;
846 indx
= elfsym
->internal_elf_sym
.st_shndx
;
850 case SHN_CR16C_FCOMMON
:
851 if (cr16c_elf_fcom_section
.name
== NULL
)
853 /* Initialize the far common section. */
854 cr16c_elf_fcom_section
.name
= ".fcommon";
855 cr16c_elf_fcom_section
.flags
= SEC_IS_COMMON
| SEC_ALLOC
;
856 cr16c_elf_fcom_section
.output_section
= &cr16c_elf_fcom_section
;
857 cr16c_elf_fcom_section
.symbol
= &cr16c_elf_fcom_symbol
;
858 cr16c_elf_fcom_section
.symbol_ptr_ptr
= &cr16c_elf_fcom_symbol_ptr
;
859 cr16c_elf_fcom_symbol
.name
= ".fcommon";
860 cr16c_elf_fcom_symbol
.flags
= BSF_SECTION_SYM
;
861 cr16c_elf_fcom_symbol
.section
= &cr16c_elf_fcom_section
;
862 cr16c_elf_fcom_symbol_ptr
= &cr16c_elf_fcom_symbol
;
864 asym
->section
= &cr16c_elf_fcom_section
;
865 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
867 case SHN_CR16C_NCOMMON
:
868 if (cr16c_elf_ncom_section
.name
== NULL
)
870 /* Initialize the far common section. */
871 cr16c_elf_ncom_section
.name
= ".ncommon";
872 cr16c_elf_ncom_section
.flags
= SEC_IS_COMMON
| SEC_ALLOC
;
873 cr16c_elf_ncom_section
.output_section
= &cr16c_elf_ncom_section
;
874 cr16c_elf_ncom_section
.symbol
= &cr16c_elf_ncom_symbol
;
875 cr16c_elf_ncom_section
.symbol_ptr_ptr
= &cr16c_elf_ncom_symbol_ptr
;
876 cr16c_elf_ncom_symbol
.name
= ".ncommon";
877 cr16c_elf_ncom_symbol
.flags
= BSF_SECTION_SYM
;
878 cr16c_elf_ncom_symbol
.section
= &cr16c_elf_ncom_section
;
879 cr16c_elf_ncom_symbol_ptr
= &cr16c_elf_ncom_symbol
;
881 asym
->section
= &cr16c_elf_ncom_section
;
882 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
887 /* Hook called by the linker routine which adds symbols from an object
888 file. We must handle the special cr16c section numbers here. */
891 elf32_cr16c_add_symbol_hook (bfd
*abfd
,
892 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
893 Elf_Internal_Sym
*sym
,
894 const char **namep ATTRIBUTE_UNUSED
,
895 flagword
*flagsp ATTRIBUTE_UNUSED
,
899 unsigned int indx
= sym
->st_shndx
;
903 case SHN_CR16C_FCOMMON
:
904 *secp
= bfd_make_section_old_way (abfd
, ".fcommon");
905 (*secp
)->flags
|= SEC_IS_COMMON
;
906 *valp
= sym
->st_size
;
908 case SHN_CR16C_NCOMMON
:
909 *secp
= bfd_make_section_old_way (abfd
, ".ncommon");
910 (*secp
)->flags
|= SEC_IS_COMMON
;
911 *valp
= sym
->st_size
;
919 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
920 const char *name ATTRIBUTE_UNUSED
,
921 Elf_Internal_Sym
*sym
,
923 struct elf_link_hash_entry
*h ATTRIBUTE_UNUSED
)
925 /* If we see a common symbol, which implies a relocatable link, then
926 if a symbol was in a special common section in an input file, mark
927 it as a special common in the output file. */
929 if (sym
->st_shndx
== SHN_COMMON
)
931 if (strcmp (input_sec
->name
, ".fcommon") == 0)
932 sym
->st_shndx
= SHN_CR16C_FCOMMON
;
933 else if (strcmp (input_sec
->name
, ".ncommon") == 0)
934 sym
->st_shndx
= SHN_CR16C_NCOMMON
;
940 /* Definitions for setting CR16C target vector. */
941 #define TARGET_LITTLE_SYM cr16c_elf32_vec
942 #define TARGET_LITTLE_NAME "elf32-cr16c"
943 #define ELF_ARCH bfd_arch_cr16c
944 #define ELF_MACHINE_CODE EM_CR
945 #define ELF_MAXPAGESIZE 0x1
946 #define elf_symbol_leading_char '_'
948 #define bfd_elf32_bfd_reloc_type_lookup elf_cr16c_reloc_type_lookup
949 #define bfd_elf32_bfd_reloc_name_lookup elf_cr16c_reloc_name_lookup
950 #define elf_info_to_howto elf_cr16c_info_to_howto
951 #define elf_info_to_howto_rel elf_cr16c_info_to_howto_rel
952 #define elf_backend_relocate_section elf32_cr16c_relocate_section
953 #define elf_backend_symbol_processing elf32_cr16c_symbol_processing
954 #define elf_backend_section_from_bfd_section elf32_cr16c_section_from_bfd_section
955 #define elf_backend_add_symbol_hook elf32_cr16c_add_symbol_hook
956 #define elf_backend_link_output_symbol_hook elf32_cr16c_link_output_symbol_hook
958 #define elf_backend_can_gc_sections 1
960 #include "elf32-target.h"