ld/testsuite/
[binutils.git] / bfd / elf32-crx.c
blob3d62b7472f9402826adb0b30af3d437fdf90e94e
1 /* BFD back-end for National Semiconductor's CRX ELF
2 Copyright 2004, 2005, 2006 Free Software Foundation, Inc.
3 Written by Tomer Levi, NSC, Israel.
5 This file is part of BFD, the Binary File Descriptor library.
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
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
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.
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
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "bfdlink.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/crx.h"
28 static reloc_howto_type *elf_crx_reloc_type_lookup
29 (bfd *, bfd_reloc_code_real_type);
30 static void elf_crx_info_to_howto
31 (bfd *, arelent *, Elf_Internal_Rela *);
32 static bfd_boolean elf32_crx_relax_delete_bytes
33 (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
34 static bfd_reloc_status_type crx_elf_final_link_relocate
35 (reloc_howto_type *, bfd *, bfd *, asection *,
36 bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
37 struct bfd_link_info *, asection *, int);
38 static bfd_boolean elf32_crx_relocate_section
39 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
40 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
41 static bfd_boolean elf32_crx_relax_section
42 (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
43 static bfd_byte * elf32_crx_get_relocated_section_contents
44 (bfd *, struct bfd_link_info *, struct bfd_link_order *,
45 bfd_byte *, bfd_boolean, asymbol **);
47 /* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
49 struct crx_reloc_map
51 bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
52 unsigned short crx_reloc_type; /* CRX relocation type. */
55 static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
57 {BFD_RELOC_NONE, R_CRX_NONE},
58 {BFD_RELOC_CRX_REL4, R_CRX_REL4},
59 {BFD_RELOC_CRX_REL8, R_CRX_REL8},
60 {BFD_RELOC_CRX_REL8_CMP, R_CRX_REL8_CMP},
61 {BFD_RELOC_CRX_REL16, R_CRX_REL16},
62 {BFD_RELOC_CRX_REL24, R_CRX_REL24},
63 {BFD_RELOC_CRX_REL32, R_CRX_REL32},
64 {BFD_RELOC_CRX_REGREL12, R_CRX_REGREL12},
65 {BFD_RELOC_CRX_REGREL22, R_CRX_REGREL22},
66 {BFD_RELOC_CRX_REGREL28, R_CRX_REGREL28},
67 {BFD_RELOC_CRX_REGREL32, R_CRX_REGREL32},
68 {BFD_RELOC_CRX_ABS16, R_CRX_ABS16},
69 {BFD_RELOC_CRX_ABS32, R_CRX_ABS32},
70 {BFD_RELOC_CRX_NUM8, R_CRX_NUM8},
71 {BFD_RELOC_CRX_NUM16, R_CRX_NUM16},
72 {BFD_RELOC_CRX_NUM32, R_CRX_NUM32},
73 {BFD_RELOC_CRX_IMM16, R_CRX_IMM16},
74 {BFD_RELOC_CRX_IMM32, R_CRX_IMM32},
75 {BFD_RELOC_CRX_SWITCH8, R_CRX_SWITCH8},
76 {BFD_RELOC_CRX_SWITCH16, R_CRX_SWITCH16},
77 {BFD_RELOC_CRX_SWITCH32, R_CRX_SWITCH32}
80 static reloc_howto_type crx_elf_howto_table[] =
82 HOWTO (R_CRX_NONE, /* type */
83 0, /* rightshift */
84 2, /* size */
85 32, /* bitsize */
86 FALSE, /* pc_relative */
87 0, /* bitpos */
88 complain_overflow_dont,/* complain_on_overflow */
89 bfd_elf_generic_reloc, /* special_function */
90 "R_CRX_NONE", /* name */
91 FALSE, /* partial_inplace */
92 0, /* src_mask */
93 0, /* dst_mask */
94 FALSE), /* pcrel_offset */
96 HOWTO (R_CRX_REL4, /* type */
97 1, /* rightshift */
98 0, /* size */
99 4, /* bitsize */
100 TRUE, /* pc_relative */
101 0, /* bitpos */
102 complain_overflow_bitfield,/* complain_on_overflow */
103 bfd_elf_generic_reloc, /* special_function */
104 "R_CRX_REL4", /* name */
105 FALSE, /* partial_inplace */
106 0xf, /* src_mask */
107 0xf, /* dst_mask */
108 FALSE), /* pcrel_offset */
110 HOWTO (R_CRX_REL8, /* type */
111 1, /* rightshift */
112 0, /* size */
113 8, /* bitsize */
114 TRUE, /* pc_relative */
115 0, /* bitpos */
116 complain_overflow_bitfield,/* complain_on_overflow */
117 bfd_elf_generic_reloc, /* special_function */
118 "R_CRX_REL8", /* name */
119 FALSE, /* partial_inplace */
120 0xff, /* src_mask */
121 0xff, /* dst_mask */
122 FALSE), /* pcrel_offset */
124 HOWTO (R_CRX_REL8_CMP, /* type */
125 1, /* rightshift */
126 0, /* size */
127 8, /* bitsize */
128 TRUE, /* pc_relative */
129 0, /* bitpos */
130 complain_overflow_bitfield,/* complain_on_overflow */
131 bfd_elf_generic_reloc, /* special_function */
132 "R_CRX_REL8_CMP", /* name */
133 FALSE, /* partial_inplace */
134 0xff, /* src_mask */
135 0xff, /* dst_mask */
136 FALSE), /* pcrel_offset */
138 HOWTO (R_CRX_REL16, /* type */
139 1, /* rightshift */
140 1, /* size */
141 16, /* bitsize */
142 TRUE, /* pc_relative */
143 0, /* bitpos */
144 complain_overflow_bitfield,/* complain_on_overflow */
145 bfd_elf_generic_reloc, /* special_function */
146 "R_CRX_REL16", /* name */
147 FALSE, /* partial_inplace */
148 0xffff, /* src_mask */
149 0xffff, /* dst_mask */
150 FALSE), /* pcrel_offset */
152 HOWTO (R_CRX_REL24, /* type */
153 1, /* rightshift */
154 2, /* size */
155 24, /* bitsize */
156 TRUE, /* pc_relative */
157 0, /* bitpos */
158 complain_overflow_bitfield,/* complain_on_overflow */
159 bfd_elf_generic_reloc, /* special_function */
160 "R_CRX_REL24", /* name */
161 FALSE, /* partial_inplace */
162 0xffffff, /* src_mask */
163 0xffffff, /* dst_mask */
164 FALSE), /* pcrel_offset */
166 HOWTO (R_CRX_REL32, /* type */
167 1, /* rightshift */
168 2, /* size */
169 32, /* bitsize */
170 TRUE, /* pc_relative */
171 0, /* bitpos */
172 complain_overflow_bitfield,/* complain_on_overflow */
173 bfd_elf_generic_reloc, /* special_function */
174 "R_CRX_REL32", /* name */
175 FALSE, /* partial_inplace */
176 0xffffffff, /* src_mask */
177 0xffffffff, /* dst_mask */
178 FALSE), /* pcrel_offset */
180 HOWTO (R_CRX_REGREL12, /* type */
181 0, /* rightshift */
182 1, /* size */
183 12, /* bitsize */
184 FALSE, /* pc_relative */
185 0, /* bitpos */
186 complain_overflow_bitfield,/* complain_on_overflow */
187 bfd_elf_generic_reloc, /* special_function */
188 "R_CRX_REGREL12", /* name */
189 FALSE, /* partial_inplace */
190 0xfff, /* src_mask */
191 0xfff, /* dst_mask */
192 FALSE), /* pcrel_offset */
194 HOWTO (R_CRX_REGREL22, /* type */
195 0, /* rightshift */
196 2, /* size */
197 22, /* bitsize */
198 FALSE, /* pc_relative */
199 0, /* bitpos */
200 complain_overflow_bitfield,/* complain_on_overflow */
201 bfd_elf_generic_reloc, /* special_function */
202 "R_CRX_REGREL22", /* name */
203 FALSE, /* partial_inplace */
204 0x3fffff, /* src_mask */
205 0x3fffff, /* dst_mask */
206 FALSE), /* pcrel_offset */
208 HOWTO (R_CRX_REGREL28, /* type */
209 0, /* rightshift */
210 2, /* size */
211 28, /* bitsize */
212 FALSE, /* pc_relative */
213 0, /* bitpos */
214 complain_overflow_bitfield,/* complain_on_overflow */
215 bfd_elf_generic_reloc, /* special_function */
216 "R_CRX_REGREL28", /* name */
217 FALSE, /* partial_inplace */
218 0xfffffff, /* src_mask */
219 0xfffffff, /* dst_mask */
220 FALSE), /* pcrel_offset */
222 HOWTO (R_CRX_REGREL32, /* type */
223 0, /* rightshift */
224 2, /* size */
225 32, /* bitsize */
226 FALSE, /* pc_relative */
227 0, /* bitpos */
228 complain_overflow_bitfield,/* complain_on_overflow */
229 bfd_elf_generic_reloc, /* special_function */
230 "R_CRX_REGREL32", /* name */
231 FALSE, /* partial_inplace */
232 0xffffffff, /* src_mask */
233 0xffffffff, /* dst_mask */
234 FALSE), /* pcrel_offset */
236 HOWTO (R_CRX_ABS16, /* type */
237 0, /* rightshift */
238 1, /* size */
239 16, /* bitsize */
240 FALSE, /* pc_relative */
241 0, /* bitpos */
242 complain_overflow_bitfield,/* complain_on_overflow */
243 bfd_elf_generic_reloc, /* special_function */
244 "R_CRX_ABS16", /* name */
245 FALSE, /* partial_inplace */
246 0xffff, /* src_mask */
247 0xffff, /* dst_mask */
248 FALSE), /* pcrel_offset */
250 HOWTO (R_CRX_ABS32, /* type */
251 0, /* rightshift */
252 2, /* size */
253 32, /* bitsize */
254 FALSE, /* pc_relative */
255 0, /* bitpos */
256 complain_overflow_bitfield,/* complain_on_overflow */
257 bfd_elf_generic_reloc, /* special_function */
258 "R_CRX_ABS32", /* name */
259 FALSE, /* partial_inplace */
260 0xffffffff, /* src_mask */
261 0xffffffff, /* dst_mask */
262 FALSE), /* pcrel_offset */
264 HOWTO (R_CRX_NUM8, /* type */
265 0, /* rightshift */
266 0, /* size */
267 8, /* bitsize */
268 FALSE, /* pc_relative */
269 0, /* bitpos */
270 complain_overflow_bitfield,/* complain_on_overflow */
271 bfd_elf_generic_reloc, /* special_function */
272 "R_CRX_NUM8", /* name */
273 FALSE, /* partial_inplace */
274 0xff, /* src_mask */
275 0xff, /* dst_mask */
276 FALSE), /* pcrel_offset */
278 HOWTO (R_CRX_NUM16, /* type */
279 0, /* rightshift */
280 1, /* size */
281 16, /* bitsize */
282 FALSE, /* pc_relative */
283 0, /* bitpos */
284 complain_overflow_bitfield,/* complain_on_overflow */
285 bfd_elf_generic_reloc, /* special_function */
286 "R_CRX_NUM16", /* name */
287 FALSE, /* partial_inplace */
288 0xffff, /* src_mask */
289 0xffff, /* dst_mask */
290 FALSE), /* pcrel_offset */
292 HOWTO (R_CRX_NUM32, /* type */
293 0, /* rightshift */
294 2, /* size */
295 32, /* bitsize */
296 FALSE, /* pc_relative */
297 0, /* bitpos */
298 complain_overflow_bitfield,/* complain_on_overflow */
299 bfd_elf_generic_reloc, /* special_function */
300 "R_CRX_NUM32", /* name */
301 FALSE, /* partial_inplace */
302 0xffffffff, /* src_mask */
303 0xffffffff, /* dst_mask */
304 FALSE), /* pcrel_offset */
306 HOWTO (R_CRX_IMM16, /* type */
307 0, /* rightshift */
308 1, /* size */
309 16, /* bitsize */
310 FALSE, /* pc_relative */
311 0, /* bitpos */
312 complain_overflow_bitfield,/* complain_on_overflow */
313 bfd_elf_generic_reloc, /* special_function */
314 "R_CRX_IMM16", /* name */
315 FALSE, /* partial_inplace */
316 0xffff, /* src_mask */
317 0xffff, /* dst_mask */
318 FALSE), /* pcrel_offset */
320 HOWTO (R_CRX_IMM32, /* type */
321 0, /* rightshift */
322 2, /* size */
323 32, /* bitsize */
324 FALSE, /* pc_relative */
325 0, /* bitpos */
326 complain_overflow_bitfield,/* complain_on_overflow */
327 bfd_elf_generic_reloc, /* special_function */
328 "R_CRX_IMM32", /* name */
329 FALSE, /* partial_inplace */
330 0xffffffff, /* src_mask */
331 0xffffffff, /* dst_mask */
332 FALSE), /* pcrel_offset */
334 /* An 8 bit switch table entry. This is generated for an expression
335 such as ``.byte L1 - L2''. The offset holds the difference
336 between the reloc address and L2. */
337 HOWTO (R_CRX_SWITCH8, /* type */
338 0, /* rightshift */
339 0, /* size (0 = byte, 1 = short, 2 = long) */
340 8, /* bitsize */
341 FALSE, /* pc_relative */
342 0, /* bitpos */
343 complain_overflow_unsigned, /* complain_on_overflow */
344 bfd_elf_generic_reloc, /* special_function */
345 "R_CRX_SWITCH8", /* name */
346 FALSE, /* partial_inplace */
347 0xff, /* src_mask */
348 0xff, /* dst_mask */
349 TRUE), /* pcrel_offset */
351 /* A 16 bit switch table entry. This is generated for an expression
352 such as ``.word L1 - L2''. The offset holds the difference
353 between the reloc address and L2. */
354 HOWTO (R_CRX_SWITCH16, /* type */
355 0, /* rightshift */
356 1, /* size (0 = byte, 1 = short, 2 = long) */
357 16, /* bitsize */
358 FALSE, /* pc_relative */
359 0, /* bitpos */
360 complain_overflow_unsigned, /* complain_on_overflow */
361 bfd_elf_generic_reloc, /* special_function */
362 "R_CRX_SWITCH16", /* name */
363 FALSE, /* partial_inplace */
364 0xffff, /* src_mask */
365 0xffff, /* dst_mask */
366 TRUE), /* pcrel_offset */
368 /* A 32 bit switch table entry. This is generated for an expression
369 such as ``.long L1 - L2''. The offset holds the difference
370 between the reloc address and L2. */
371 HOWTO (R_CRX_SWITCH32, /* type */
372 0, /* rightshift */
373 2, /* size (0 = byte, 1 = short, 2 = long) */
374 32, /* bitsize */
375 FALSE, /* pc_relative */
376 0, /* bitpos */
377 complain_overflow_unsigned, /* complain_on_overflow */
378 bfd_elf_generic_reloc, /* special_function */
379 "R_CRX_SWITCH32", /* name */
380 FALSE, /* partial_inplace */
381 0xffffffff, /* src_mask */
382 0xffffffff, /* dst_mask */
383 TRUE) /* pcrel_offset */
386 /* Retrieve a howto ptr using a BFD reloc_code. */
388 static reloc_howto_type *
389 elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
390 bfd_reloc_code_real_type code)
392 unsigned int i;
394 for (i = 0; i < R_CRX_MAX; i++)
395 if (code == crx_reloc_map[i].bfd_reloc_enum)
396 return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
398 printf ("This relocation Type is not supported -0x%x\n", code);
399 return 0;
402 /* Retrieve a howto ptr using an internal relocation entry. */
404 static void
405 elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
406 Elf_Internal_Rela *dst)
408 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
409 BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
410 cache_ptr->howto = &crx_elf_howto_table[r_type];
413 /* Perform a relocation as part of a final link. */
415 static bfd_reloc_status_type
416 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
417 bfd *output_bfd ATTRIBUTE_UNUSED,
418 asection *input_section, bfd_byte *contents,
419 bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
420 struct bfd_link_info *info ATTRIBUTE_UNUSED,
421 asection *sec ATTRIBUTE_UNUSED,
422 int is_local ATTRIBUTE_UNUSED)
424 unsigned short r_type = howto->type;
425 bfd_byte *hit_data = contents + offset;
426 bfd_vma reloc_bits, check;
428 switch (r_type)
430 case R_CRX_IMM16:
431 case R_CRX_IMM32:
432 case R_CRX_ABS16:
433 case R_CRX_ABS32:
434 case R_CRX_REL8_CMP:
435 case R_CRX_REL16:
436 case R_CRX_REL24:
437 case R_CRX_REL32:
438 case R_CRX_REGREL12:
439 case R_CRX_REGREL22:
440 case R_CRX_REGREL28:
441 case R_CRX_REGREL32:
442 /* 'hit_data' is relative to the start of the instruction, not the
443 relocation offset. Advance it to account for the exact offset. */
444 hit_data += 2;
445 break;
447 case R_CRX_REL4:
448 /* This relocation type is used only in 'Branch if Equal to 0'
449 instructions and requires special handling. */
450 Rvalue -= 1;
451 break;
453 case R_CRX_NONE:
454 return bfd_reloc_ok;
455 break;
457 case R_CRX_SWITCH8:
458 case R_CRX_SWITCH16:
459 case R_CRX_SWITCH32:
460 /* We only care about the addend, where the difference between
461 expressions is kept. */
462 Rvalue = 0;
464 default:
465 break;
468 if (howto->pc_relative)
470 /* Subtract the address of the section containing the location. */
471 Rvalue -= (input_section->output_section->vma
472 + input_section->output_offset);
473 /* Subtract the position of the location within the section. */
474 Rvalue -= offset;
477 /* Add in supplied addend. */
478 Rvalue += addend;
480 /* Complain if the bitfield overflows, whether it is considered
481 as signed or unsigned. */
482 check = Rvalue >> howto->rightshift;
484 /* Assumes two's complement. This expression avoids
485 overflow if howto->bitsize is the number of bits in
486 bfd_vma. */
487 reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
489 if (((bfd_vma) check & ~reloc_bits) != 0
490 && (((bfd_vma) check & ~reloc_bits)
491 != (-(bfd_vma) 1 & ~reloc_bits)))
493 /* The above right shift is incorrect for a signed
494 value. See if turning on the upper bits fixes the
495 overflow. */
496 if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
498 check |= ((bfd_vma) - 1
499 & ~((bfd_vma) - 1
500 >> howto->rightshift));
501 if (((bfd_vma) check & ~reloc_bits)
502 != (-(bfd_vma) 1 & ~reloc_bits))
503 return bfd_reloc_overflow;
505 else
506 return bfd_reloc_overflow;
509 /* Drop unwanted bits from the value we are relocating to. */
510 Rvalue >>= (bfd_vma) howto->rightshift;
512 /* Apply dst_mask to select only relocatable part of the insn. */
513 Rvalue &= howto->dst_mask;
515 switch (howto->size)
517 case 0:
518 if (r_type == R_CRX_REL4)
520 Rvalue <<= 4;
521 Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
524 bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
525 break;
527 case 1:
528 if (r_type == R_CRX_REGREL12)
529 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
531 bfd_put_16 (input_bfd, Rvalue, hit_data);
532 break;
534 case 2:
535 if (r_type == R_CRX_REL24
536 || r_type == R_CRX_REGREL22
537 || r_type == R_CRX_REGREL28)
538 Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
539 bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
541 if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
542 /* Relocation on DATA is purely little-endian, that is, for a
543 multi-byte datum, the lowest address in memory contains the
544 little end of the datum, that is, the least significant byte.
545 Therefore we use BFD's byte Putting functions. */
546 bfd_put_32 (input_bfd, Rvalue, hit_data);
547 else
548 /* Relocation on INSTRUCTIONS is different : Instructions are
549 word-addressable, that is, each word itself is arranged according
550 to little-endian convention, whereas the words are arranged with
551 respect to one another in BIG ENDIAN fashion.
552 When there is an immediate value that spans a word boundary, it is
553 split in a big-endian way with respect to the words. */
555 bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
556 bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
558 break;
560 default:
561 return bfd_reloc_notsupported;
564 return bfd_reloc_ok;
567 /* Delete some bytes from a section while relaxing. */
569 static bfd_boolean
570 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
571 asection *sec, bfd_vma addr, int count)
573 Elf_Internal_Shdr *symtab_hdr;
574 unsigned int sec_shndx;
575 bfd_byte *contents;
576 Elf_Internal_Rela *irel, *irelend;
577 Elf_Internal_Rela *irelalign;
578 bfd_vma toaddr;
579 Elf_Internal_Sym *isym;
580 Elf_Internal_Sym *isymend;
581 struct elf_link_hash_entry **sym_hashes;
582 struct elf_link_hash_entry **end_hashes;
583 struct elf_link_hash_entry **start_hashes;
584 unsigned int symcount;
586 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
588 contents = elf_section_data (sec)->this_hdr.contents;
590 /* The deletion must stop at the next ALIGN reloc for an aligment
591 power larger than the number of bytes we are deleting. */
593 irelalign = NULL;
594 toaddr = sec->size;
596 irel = elf_section_data (sec)->relocs;
597 irelend = irel + sec->reloc_count;
599 /* Actually delete the bytes. */
600 memmove (contents + addr, contents + addr + count,
601 (size_t) (toaddr - addr - count));
602 sec->size -= count;
604 /* Adjust all the relocs. */
605 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
607 /* Get the new reloc address. */
608 if ((irel->r_offset > addr
609 && irel->r_offset < toaddr))
610 irel->r_offset -= count;
613 /* Adjust the local symbols defined in this section. */
614 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
615 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
616 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
618 if (isym->st_shndx == sec_shndx
619 && isym->st_value > addr
620 && isym->st_value < toaddr)
622 /* Adjust the addend of SWITCH relocations in this section,
623 which reference this local symbol. */
624 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
626 unsigned long r_symndx;
627 Elf_Internal_Sym *rsym;
628 bfd_vma addsym, subsym;
630 /* Skip if not a SWITCH relocation. */
631 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
632 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
633 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
634 continue;
636 r_symndx = ELF32_R_SYM (irel->r_info);
637 rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
639 /* Skip if not the local adjusted symbol. */
640 if (rsym != isym)
641 continue;
643 addsym = isym->st_value;
644 subsym = addsym - irel->r_addend;
646 /* Fix the addend only when -->> (addsym > addr >= subsym). */
647 if (subsym <= addr)
648 irel->r_addend -= count;
649 else
650 continue;
653 isym->st_value -= count;
657 /* Now adjust the global symbols defined in this section. */
658 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
659 - symtab_hdr->sh_info);
660 sym_hashes = start_hashes = elf_sym_hashes (abfd);
661 end_hashes = sym_hashes + symcount;
663 for (; sym_hashes < end_hashes; sym_hashes++)
665 struct elf_link_hash_entry *sym_hash = *sym_hashes;
667 /* The '--wrap SYMBOL' option is causing a pain when the object file,
668 containing the definition of __wrap_SYMBOL, includes a direct
669 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
670 the same symbol (which is __wrap_SYMBOL), but still exist as two
671 different symbols in 'sym_hashes', we don't want to adjust
672 the global symbol __wrap_SYMBOL twice.
673 This check is only relevant when symbols are being wrapped. */
674 if (link_info->wrap_hash != NULL)
676 struct elf_link_hash_entry **cur_sym_hashes;
678 /* Loop only over the symbols whom been already checked. */
679 for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
680 cur_sym_hashes++)
682 /* If the current symbol is identical to 'sym_hash', that means
683 the symbol was already adjusted (or at least checked). */
684 if (*cur_sym_hashes == sym_hash)
685 break;
687 /* Don't adjust the symbol again. */
688 if (cur_sym_hashes < sym_hashes)
689 continue;
692 if ((sym_hash->root.type == bfd_link_hash_defined
693 || sym_hash->root.type == bfd_link_hash_defweak)
694 && sym_hash->root.u.def.section == sec
695 && sym_hash->root.u.def.value > addr
696 && sym_hash->root.u.def.value < toaddr)
697 sym_hash->root.u.def.value -= count;
700 return TRUE;
703 /* This is a version of bfd_generic_get_relocated_section_contents
704 which uses elf32_crx_relocate_section. */
706 static bfd_byte *
707 elf32_crx_get_relocated_section_contents (bfd *output_bfd,
708 struct bfd_link_info *link_info,
709 struct bfd_link_order *link_order,
710 bfd_byte *data,
711 bfd_boolean relocatable,
712 asymbol **symbols)
714 Elf_Internal_Shdr *symtab_hdr;
715 asection *input_section = link_order->u.indirect.section;
716 bfd *input_bfd = input_section->owner;
717 asection **sections = NULL;
718 Elf_Internal_Rela *internal_relocs = NULL;
719 Elf_Internal_Sym *isymbuf = NULL;
721 /* We only need to handle the case of relaxing, or of having a
722 particular set of section contents, specially. */
723 if (relocatable
724 || elf_section_data (input_section)->this_hdr.contents == NULL)
725 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
726 link_order, data,
727 relocatable,
728 symbols);
730 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
732 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
733 (size_t) input_section->size);
735 if ((input_section->flags & SEC_RELOC) != 0
736 && input_section->reloc_count > 0)
738 Elf_Internal_Sym *isym;
739 Elf_Internal_Sym *isymend;
740 asection **secpp;
741 bfd_size_type amt;
743 internal_relocs = (_bfd_elf_link_read_relocs
744 (input_bfd, input_section, (PTR) NULL,
745 (Elf_Internal_Rela *) NULL, FALSE));
746 if (internal_relocs == NULL)
747 goto error_return;
749 if (symtab_hdr->sh_info != 0)
751 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
752 if (isymbuf == NULL)
753 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
754 symtab_hdr->sh_info, 0,
755 NULL, NULL, NULL);
756 if (isymbuf == NULL)
757 goto error_return;
760 amt = symtab_hdr->sh_info;
761 amt *= sizeof (asection *);
762 sections = bfd_malloc (amt);
763 if (sections == NULL && amt != 0)
764 goto error_return;
766 isymend = isymbuf + symtab_hdr->sh_info;
767 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
769 asection *isec;
771 if (isym->st_shndx == SHN_UNDEF)
772 isec = bfd_und_section_ptr;
773 else if (isym->st_shndx == SHN_ABS)
774 isec = bfd_abs_section_ptr;
775 else if (isym->st_shndx == SHN_COMMON)
776 isec = bfd_com_section_ptr;
777 else
778 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
780 *secpp = isec;
783 if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
784 input_section, data, internal_relocs,
785 isymbuf, sections))
786 goto error_return;
788 if (sections != NULL)
789 free (sections);
790 if (isymbuf != NULL
791 && symtab_hdr->contents != (unsigned char *) isymbuf)
792 free (isymbuf);
793 if (elf_section_data (input_section)->relocs != internal_relocs)
794 free (internal_relocs);
797 return data;
799 error_return:
800 if (sections != NULL)
801 free (sections);
802 if (isymbuf != NULL
803 && symtab_hdr->contents != (unsigned char *) isymbuf)
804 free (isymbuf);
805 if (internal_relocs != NULL
806 && elf_section_data (input_section)->relocs != internal_relocs)
807 free (internal_relocs);
808 return NULL;
811 /* Relocate a CRX ELF section. */
813 static bfd_boolean
814 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
815 bfd *input_bfd, asection *input_section,
816 bfd_byte *contents, Elf_Internal_Rela *relocs,
817 Elf_Internal_Sym *local_syms,
818 asection **local_sections)
820 Elf_Internal_Shdr *symtab_hdr;
821 struct elf_link_hash_entry **sym_hashes;
822 Elf_Internal_Rela *rel, *relend;
824 if (info->relocatable)
825 return TRUE;
827 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
828 sym_hashes = elf_sym_hashes (input_bfd);
830 rel = relocs;
831 relend = relocs + input_section->reloc_count;
832 for (; rel < relend; rel++)
834 int r_type;
835 reloc_howto_type *howto;
836 unsigned long r_symndx;
837 Elf_Internal_Sym *sym;
838 asection *sec;
839 struct elf_link_hash_entry *h;
840 bfd_vma relocation;
841 bfd_reloc_status_type r;
843 r_symndx = ELF32_R_SYM (rel->r_info);
844 r_type = ELF32_R_TYPE (rel->r_info);
845 howto = crx_elf_howto_table + (r_type);
847 h = NULL;
848 sym = NULL;
849 sec = NULL;
850 if (r_symndx < symtab_hdr->sh_info)
852 sym = local_syms + r_symndx;
853 sec = local_sections[r_symndx];
854 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
856 else
858 bfd_boolean unresolved_reloc, warned;
860 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
861 r_symndx, symtab_hdr, sym_hashes,
862 h, sec, relocation,
863 unresolved_reloc, warned);
866 r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
867 input_section,
868 contents, rel->r_offset,
869 relocation, rel->r_addend,
870 info, sec, h == NULL);
872 if (r != bfd_reloc_ok)
874 const char *name;
875 const char *msg = (const char *) 0;
877 if (h != NULL)
878 name = h->root.root.string;
879 else
881 name = (bfd_elf_string_from_elf_section
882 (input_bfd, symtab_hdr->sh_link, sym->st_name));
883 if (name == NULL || *name == '\0')
884 name = bfd_section_name (input_bfd, sec);
887 switch (r)
889 case bfd_reloc_overflow:
890 if (!((*info->callbacks->reloc_overflow)
891 (info, (h ? &h->root : NULL), name, howto->name,
892 (bfd_vma) 0, input_bfd, input_section,
893 rel->r_offset)))
894 return FALSE;
895 break;
897 case bfd_reloc_undefined:
898 if (!((*info->callbacks->undefined_symbol)
899 (info, name, input_bfd, input_section,
900 rel->r_offset, TRUE)))
901 return FALSE;
902 break;
904 case bfd_reloc_outofrange:
905 msg = _("internal error: out of range error");
906 goto common_error;
908 case bfd_reloc_notsupported:
909 msg = _("internal error: unsupported relocation error");
910 goto common_error;
912 case bfd_reloc_dangerous:
913 msg = _("internal error: dangerous error");
914 goto common_error;
916 default:
917 msg = _("internal error: unknown error");
918 /* Fall through. */
920 common_error:
921 if (!((*info->callbacks->warning)
922 (info, msg, name, input_bfd, input_section,
923 rel->r_offset)))
924 return FALSE;
925 break;
930 return TRUE;
933 /* This function handles relaxing for the CRX.
935 There's quite a few relaxing opportunites available on the CRX:
937 * bal/bcond:32 -> bal/bcond:16 2 bytes
938 * bcond:16 -> bcond:8 2 bytes
939 * cmpbcond:24 -> cmpbcond:8 2 bytes
940 * arithmetic imm32 -> arithmetic imm16 2 bytes
942 Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
944 static bfd_boolean
945 elf32_crx_relax_section (bfd *abfd, asection *sec,
946 struct bfd_link_info *link_info, bfd_boolean *again)
948 Elf_Internal_Shdr *symtab_hdr;
949 Elf_Internal_Rela *internal_relocs;
950 Elf_Internal_Rela *irel, *irelend;
951 bfd_byte *contents = NULL;
952 Elf_Internal_Sym *isymbuf = NULL;
954 /* Assume nothing changes. */
955 *again = FALSE;
957 /* We don't have to do anything for a relocatable link, if
958 this section does not have relocs, or if this is not a
959 code section. */
960 if (link_info->relocatable
961 || (sec->flags & SEC_RELOC) == 0
962 || sec->reloc_count == 0
963 || (sec->flags & SEC_CODE) == 0)
964 return TRUE;
966 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
968 /* Get a copy of the native relocations. */
969 internal_relocs = (_bfd_elf_link_read_relocs
970 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
971 link_info->keep_memory));
972 if (internal_relocs == NULL)
973 goto error_return;
975 /* Walk through them looking for relaxing opportunities. */
976 irelend = internal_relocs + sec->reloc_count;
977 for (irel = internal_relocs; irel < irelend; irel++)
979 bfd_vma symval;
981 /* If this isn't something that can be relaxed, then ignore
982 this reloc. */
983 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
984 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
985 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
986 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
987 continue;
989 /* Get the section contents if we haven't done so already. */
990 if (contents == NULL)
992 /* Get cached copy if it exists. */
993 if (elf_section_data (sec)->this_hdr.contents != NULL)
994 contents = elf_section_data (sec)->this_hdr.contents;
995 /* Go get them off disk. */
996 else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
997 goto error_return;
1000 /* Read this BFD's local symbols if we haven't done so already. */
1001 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1003 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1004 if (isymbuf == NULL)
1005 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1006 symtab_hdr->sh_info, 0,
1007 NULL, NULL, NULL);
1008 if (isymbuf == NULL)
1009 goto error_return;
1012 /* Get the value of the symbol referred to by the reloc. */
1013 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1015 /* A local symbol. */
1016 Elf_Internal_Sym *isym;
1017 asection *sym_sec;
1019 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1020 if (isym->st_shndx == SHN_UNDEF)
1021 sym_sec = bfd_und_section_ptr;
1022 else if (isym->st_shndx == SHN_ABS)
1023 sym_sec = bfd_abs_section_ptr;
1024 else if (isym->st_shndx == SHN_COMMON)
1025 sym_sec = bfd_com_section_ptr;
1026 else
1027 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1028 symval = (isym->st_value
1029 + sym_sec->output_section->vma
1030 + sym_sec->output_offset);
1032 else
1034 unsigned long indx;
1035 struct elf_link_hash_entry *h;
1037 /* An external symbol. */
1038 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1039 h = elf_sym_hashes (abfd)[indx];
1040 BFD_ASSERT (h != NULL);
1042 if (h->root.type != bfd_link_hash_defined
1043 && h->root.type != bfd_link_hash_defweak)
1044 /* This appears to be a reference to an undefined
1045 symbol. Just ignore it--it will be caught by the
1046 regular reloc processing. */
1047 continue;
1049 symval = (h->root.u.def.value
1050 + h->root.u.def.section->output_section->vma
1051 + h->root.u.def.section->output_offset);
1054 /* For simplicity of coding, we are going to modify the section
1055 contents, the section relocs, and the BFD symbol table. We
1056 must tell the rest of the code not to free up this
1057 information. It would be possible to instead create a table
1058 of changes which have to be made, as is done in coff-mips.c;
1059 that would be more work, but would require less memory when
1060 the linker is run. */
1062 /* Try to turn a 32bit pc-relative branch/call into
1063 a 16bit pc-relative branch/call. */
1064 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
1066 bfd_vma value = symval;
1068 /* Deal with pc-relative gunk. */
1069 value -= (sec->output_section->vma + sec->output_offset);
1070 value -= irel->r_offset;
1071 value += irel->r_addend;
1073 /* See if the value will fit in 16 bits, note the high value is
1074 0xfffe + 2 as the target will be two bytes closer if we are
1075 able to relax. */
1076 if ((long) value < 0x10000 && (long) value > -0x10002)
1078 unsigned short code;
1080 /* Get the opcode. */
1081 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1083 /* Verify it's a 'bal'/'bcond' and fix the opcode. */
1084 if ((code & 0xfff0) == 0x3170)
1085 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1086 else if ((code & 0xf0ff) == 0x707f)
1087 bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
1088 else
1089 continue;
1091 /* Note that we've changed the relocs, section contents, etc. */
1092 elf_section_data (sec)->relocs = internal_relocs;
1093 elf_section_data (sec)->this_hdr.contents = contents;
1094 symtab_hdr->contents = (unsigned char *) isymbuf;
1096 /* Fix the relocation's type. */
1097 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1098 R_CRX_REL16);
1100 /* Delete two bytes of data. */
1101 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1102 irel->r_offset + 2, 2))
1103 goto error_return;
1105 /* That will change things, so, we should relax again.
1106 Note that this is not required, and it may be slow. */
1107 *again = TRUE;
1111 /* Try to turn a 16bit pc-relative branch into an
1112 8bit pc-relative branch. */
1113 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
1115 bfd_vma value = symval;
1117 /* Deal with pc-relative gunk. */
1118 value -= (sec->output_section->vma + sec->output_offset);
1119 value -= irel->r_offset;
1120 value += irel->r_addend;
1122 /* See if the value will fit in 8 bits, note the high value is
1123 0xfc + 2 as the target will be two bytes closer if we are
1124 able to relax. */
1125 if ((long) value < 0xfe && (long) value > -0x100)
1127 unsigned short code;
1129 /* Get the opcode. */
1130 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1132 /* Verify it's a 'bcond' opcode. */
1133 if ((code & 0xf0ff) != 0x707e)
1134 continue;
1136 /* Note that we've changed the relocs, section contents, etc. */
1137 elf_section_data (sec)->relocs = internal_relocs;
1138 elf_section_data (sec)->this_hdr.contents = contents;
1139 symtab_hdr->contents = (unsigned char *) isymbuf;
1141 /* Fix the relocation's type. */
1142 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1143 R_CRX_REL8);
1145 /* Delete two bytes of data. */
1146 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1147 irel->r_offset + 2, 2))
1148 goto error_return;
1150 /* That will change things, so, we should relax again.
1151 Note that this is not required, and it may be slow. */
1152 *again = TRUE;
1156 /* Try to turn a 24bit pc-relative cmp&branch into
1157 an 8bit pc-relative cmp&branch. */
1158 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
1160 bfd_vma value = symval;
1162 /* Deal with pc-relative gunk. */
1163 value -= (sec->output_section->vma + sec->output_offset);
1164 value -= irel->r_offset;
1165 value += irel->r_addend;
1167 /* See if the value will fit in 8 bits, note the high value is
1168 0x7e + 2 as the target will be two bytes closer if we are
1169 able to relax. */
1170 if ((long) value < 0x100 && (long) value > -0x100)
1172 unsigned short code;
1174 /* Get the opcode. */
1175 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1177 /* Verify it's a 'cmp&branch' opcode. */
1178 if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
1179 && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
1180 && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
1181 /* Or a Co-processor branch ('bcop'). */
1182 && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
1183 continue;
1185 /* Note that we've changed the relocs, section contents, etc. */
1186 elf_section_data (sec)->relocs = internal_relocs;
1187 elf_section_data (sec)->this_hdr.contents = contents;
1188 symtab_hdr->contents = (unsigned char *) isymbuf;
1190 /* Fix the opcode. */
1191 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1193 /* Fix the relocation's type. */
1194 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1195 R_CRX_REL8_CMP);
1197 /* Delete two bytes of data. */
1198 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1199 irel->r_offset + 4, 2))
1200 goto error_return;
1202 /* That will change things, so, we should relax again.
1203 Note that this is not required, and it may be slow. */
1204 *again = TRUE;
1208 /* Try to turn a 32bit immediate address into
1209 a 16bit immediate address. */
1210 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
1212 bfd_vma value = symval;
1214 /* See if the value will fit in 16 bits. */
1215 if ((long) value < 0x7fff && (long) value > -0x8000)
1217 unsigned short code;
1219 /* Get the opcode. */
1220 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1222 /* Verify it's a 'arithmetic double'. */
1223 if ((code & 0xf0f0) != 0x20f0)
1224 continue;
1226 /* Note that we've changed the relocs, section contents, etc. */
1227 elf_section_data (sec)->relocs = internal_relocs;
1228 elf_section_data (sec)->this_hdr.contents = contents;
1229 symtab_hdr->contents = (unsigned char *) isymbuf;
1231 /* Fix the opcode. */
1232 bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
1234 /* Fix the relocation's type. */
1235 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1236 R_CRX_IMM16);
1238 /* Delete two bytes of data. */
1239 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1240 irel->r_offset + 2, 2))
1241 goto error_return;
1243 /* That will change things, so, we should relax again.
1244 Note that this is not required, and it may be slow. */
1245 *again = TRUE;
1250 if (isymbuf != NULL
1251 && symtab_hdr->contents != (unsigned char *) isymbuf)
1253 if (! link_info->keep_memory)
1254 free (isymbuf);
1255 else
1257 /* Cache the symbols for elf_link_input_bfd. */
1258 symtab_hdr->contents = (unsigned char *) isymbuf;
1262 if (contents != NULL
1263 && elf_section_data (sec)->this_hdr.contents != contents)
1265 if (! link_info->keep_memory)
1266 free (contents);
1267 else
1269 /* Cache the section contents for elf_link_input_bfd. */
1270 elf_section_data (sec)->this_hdr.contents = contents;
1274 if (internal_relocs != NULL
1275 && elf_section_data (sec)->relocs != internal_relocs)
1276 free (internal_relocs);
1278 return TRUE;
1280 error_return:
1281 if (isymbuf != NULL
1282 && symtab_hdr->contents != (unsigned char *) isymbuf)
1283 free (isymbuf);
1284 if (contents != NULL
1285 && elf_section_data (sec)->this_hdr.contents != contents)
1286 free (contents);
1287 if (internal_relocs != NULL
1288 && elf_section_data (sec)->relocs != internal_relocs)
1289 free (internal_relocs);
1291 return FALSE;
1294 /* Definitions for setting CRX target vector. */
1295 #define TARGET_LITTLE_SYM bfd_elf32_crx_vec
1296 #define TARGET_LITTLE_NAME "elf32-crx"
1297 #define ELF_ARCH bfd_arch_crx
1298 #define ELF_MACHINE_CODE EM_CRX
1299 #define ELF_MAXPAGESIZE 0x1
1300 #define elf_symbol_leading_char '_'
1302 #define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup
1303 #define elf_info_to_howto elf_crx_info_to_howto
1304 #define elf_info_to_howto_rel 0
1305 #define elf_backend_relocate_section elf32_crx_relocate_section
1306 #define bfd_elf32_bfd_relax_section elf32_crx_relax_section
1307 #define bfd_elf32_bfd_get_relocated_section_contents \
1308 elf32_crx_get_relocated_section_contents
1309 #define elf_backend_can_gc_sections 1
1310 #define elf_backend_rela_normal 1
1312 #include "elf32-target.h"