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