bfd/
[deliverable/binutils-gdb.git] / bfd / elf32-crx.c
1 /* BFD back-end for National Semiconductor's CRX ELF
2 Copyright 2004, 2005, 2006, 2007 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 2 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, MA 02110-1301, USA. */
20
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "bfdlink.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/crx.h"
27
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 **);
46
47 /* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
48
49 struct crx_reloc_map
50 {
51 bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
52 unsigned short crx_reloc_type; /* CRX relocation type. */
53 };
54
55 static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
56 {
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}
78 };
79
80 static reloc_howto_type crx_elf_howto_table[] =
81 {
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 */
95
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 */
109
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 */
123
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 */
137
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 */
151
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 */
165
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 */
179
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 */
193
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 */
207
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 */
221
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 */
235
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 */
249
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 */
263
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 */
277
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 */
291
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 */
305
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 */
319
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 */
333
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 */
350
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 */
367
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 */
384 };
385
386 /* Retrieve a howto ptr using a BFD reloc_code. */
387
388 static reloc_howto_type *
389 elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
390 bfd_reloc_code_real_type code)
391 {
392 unsigned int i;
393
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];
397
398 printf ("This relocation Type is not supported -0x%x\n", code);
399 return 0;
400 }
401
402 static reloc_howto_type *
403 elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
404 const char *r_name)
405 {
406 unsigned int i;
407
408 for (i = 0;
409 i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]);
410 i++)
411 if (crx_elf_howto_table[i].name != NULL
412 && strcasecmp (crx_elf_howto_table[i].name, r_name) == 0)
413 return &crx_elf_howto_table[i];
414
415 return NULL;
416 }
417
418 /* Retrieve a howto ptr using an internal relocation entry. */
419
420 static void
421 elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
422 Elf_Internal_Rela *dst)
423 {
424 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
425 BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
426 cache_ptr->howto = &crx_elf_howto_table[r_type];
427 }
428
429 /* Perform a relocation as part of a final link. */
430
431 static bfd_reloc_status_type
432 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
433 bfd *output_bfd ATTRIBUTE_UNUSED,
434 asection *input_section, bfd_byte *contents,
435 bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
436 struct bfd_link_info *info ATTRIBUTE_UNUSED,
437 asection *sec ATTRIBUTE_UNUSED,
438 int is_local ATTRIBUTE_UNUSED)
439 {
440 unsigned short r_type = howto->type;
441 bfd_byte *hit_data = contents + offset;
442 bfd_vma reloc_bits, check;
443
444 switch (r_type)
445 {
446 case R_CRX_IMM16:
447 case R_CRX_IMM32:
448 case R_CRX_ABS16:
449 case R_CRX_ABS32:
450 case R_CRX_REL8_CMP:
451 case R_CRX_REL16:
452 case R_CRX_REL24:
453 case R_CRX_REL32:
454 case R_CRX_REGREL12:
455 case R_CRX_REGREL22:
456 case R_CRX_REGREL28:
457 case R_CRX_REGREL32:
458 /* 'hit_data' is relative to the start of the instruction, not the
459 relocation offset. Advance it to account for the exact offset. */
460 hit_data += 2;
461 break;
462
463 case R_CRX_REL4:
464 /* This relocation type is used only in 'Branch if Equal to 0'
465 instructions and requires special handling. */
466 Rvalue -= 1;
467 break;
468
469 case R_CRX_NONE:
470 return bfd_reloc_ok;
471 break;
472
473 case R_CRX_SWITCH8:
474 case R_CRX_SWITCH16:
475 case R_CRX_SWITCH32:
476 /* We only care about the addend, where the difference between
477 expressions is kept. */
478 Rvalue = 0;
479
480 default:
481 break;
482 }
483
484 if (howto->pc_relative)
485 {
486 /* Subtract the address of the section containing the location. */
487 Rvalue -= (input_section->output_section->vma
488 + input_section->output_offset);
489 /* Subtract the position of the location within the section. */
490 Rvalue -= offset;
491 }
492
493 /* Add in supplied addend. */
494 Rvalue += addend;
495
496 /* Complain if the bitfield overflows, whether it is considered
497 as signed or unsigned. */
498 check = Rvalue >> howto->rightshift;
499
500 /* Assumes two's complement. This expression avoids
501 overflow if howto->bitsize is the number of bits in
502 bfd_vma. */
503 reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
504
505 if (((bfd_vma) check & ~reloc_bits) != 0
506 && (((bfd_vma) check & ~reloc_bits)
507 != (-(bfd_vma) 1 & ~reloc_bits)))
508 {
509 /* The above right shift is incorrect for a signed
510 value. See if turning on the upper bits fixes the
511 overflow. */
512 if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
513 {
514 check |= ((bfd_vma) - 1
515 & ~((bfd_vma) - 1
516 >> howto->rightshift));
517 if (((bfd_vma) check & ~reloc_bits)
518 != (-(bfd_vma) 1 & ~reloc_bits))
519 return bfd_reloc_overflow;
520 }
521 else
522 return bfd_reloc_overflow;
523 }
524
525 /* Drop unwanted bits from the value we are relocating to. */
526 Rvalue >>= (bfd_vma) howto->rightshift;
527
528 /* Apply dst_mask to select only relocatable part of the insn. */
529 Rvalue &= howto->dst_mask;
530
531 switch (howto->size)
532 {
533 case 0:
534 if (r_type == R_CRX_REL4)
535 {
536 Rvalue <<= 4;
537 Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
538 }
539
540 bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
541 break;
542
543 case 1:
544 if (r_type == R_CRX_REGREL12)
545 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
546
547 bfd_put_16 (input_bfd, Rvalue, hit_data);
548 break;
549
550 case 2:
551 if (r_type == R_CRX_REL24
552 || r_type == R_CRX_REGREL22
553 || r_type == R_CRX_REGREL28)
554 Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
555 bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
556
557 if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
558 /* Relocation on DATA is purely little-endian, that is, for a
559 multi-byte datum, the lowest address in memory contains the
560 little end of the datum, that is, the least significant byte.
561 Therefore we use BFD's byte Putting functions. */
562 bfd_put_32 (input_bfd, Rvalue, hit_data);
563 else
564 /* Relocation on INSTRUCTIONS is different : Instructions are
565 word-addressable, that is, each word itself is arranged according
566 to little-endian convention, whereas the words are arranged with
567 respect to one another in BIG ENDIAN fashion.
568 When there is an immediate value that spans a word boundary, it is
569 split in a big-endian way with respect to the words. */
570 {
571 bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
572 bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
573 }
574 break;
575
576 default:
577 return bfd_reloc_notsupported;
578 }
579
580 return bfd_reloc_ok;
581 }
582
583 /* Delete some bytes from a section while relaxing. */
584
585 static bfd_boolean
586 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
587 asection *sec, bfd_vma addr, int count)
588 {
589 Elf_Internal_Shdr *symtab_hdr;
590 unsigned int sec_shndx;
591 bfd_byte *contents;
592 Elf_Internal_Rela *irel, *irelend;
593 Elf_Internal_Rela *irelalign;
594 bfd_vma toaddr;
595 Elf_Internal_Sym *isym;
596 Elf_Internal_Sym *isymend;
597 struct elf_link_hash_entry **sym_hashes;
598 struct elf_link_hash_entry **end_hashes;
599 struct elf_link_hash_entry **start_hashes;
600 unsigned int symcount;
601
602 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
603
604 contents = elf_section_data (sec)->this_hdr.contents;
605
606 /* The deletion must stop at the next ALIGN reloc for an aligment
607 power larger than the number of bytes we are deleting. */
608
609 irelalign = NULL;
610 toaddr = sec->size;
611
612 irel = elf_section_data (sec)->relocs;
613 irelend = irel + sec->reloc_count;
614
615 /* Actually delete the bytes. */
616 memmove (contents + addr, contents + addr + count,
617 (size_t) (toaddr - addr - count));
618 sec->size -= count;
619
620 /* Adjust all the relocs. */
621 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
622 {
623 /* Get the new reloc address. */
624 if ((irel->r_offset > addr
625 && irel->r_offset < toaddr))
626 irel->r_offset -= count;
627 }
628
629 /* Adjust the local symbols defined in this section. */
630 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
631 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
632 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
633 {
634 if (isym->st_shndx == sec_shndx
635 && isym->st_value > addr
636 && isym->st_value < toaddr)
637 {
638 /* Adjust the addend of SWITCH relocations in this section,
639 which reference this local symbol. */
640 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
641 {
642 unsigned long r_symndx;
643 Elf_Internal_Sym *rsym;
644 bfd_vma addsym, subsym;
645
646 /* Skip if not a SWITCH relocation. */
647 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
648 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
649 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
650 continue;
651
652 r_symndx = ELF32_R_SYM (irel->r_info);
653 rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
654
655 /* Skip if not the local adjusted symbol. */
656 if (rsym != isym)
657 continue;
658
659 addsym = isym->st_value;
660 subsym = addsym - irel->r_addend;
661
662 /* Fix the addend only when -->> (addsym > addr >= subsym). */
663 if (subsym <= addr)
664 irel->r_addend -= count;
665 else
666 continue;
667 }
668
669 isym->st_value -= count;
670 }
671 }
672
673 /* Now adjust the global symbols defined in this section. */
674 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
675 - symtab_hdr->sh_info);
676 sym_hashes = start_hashes = elf_sym_hashes (abfd);
677 end_hashes = sym_hashes + symcount;
678
679 for (; sym_hashes < end_hashes; sym_hashes++)
680 {
681 struct elf_link_hash_entry *sym_hash = *sym_hashes;
682
683 /* The '--wrap SYMBOL' option is causing a pain when the object file,
684 containing the definition of __wrap_SYMBOL, includes a direct
685 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
686 the same symbol (which is __wrap_SYMBOL), but still exist as two
687 different symbols in 'sym_hashes', we don't want to adjust
688 the global symbol __wrap_SYMBOL twice.
689 This check is only relevant when symbols are being wrapped. */
690 if (link_info->wrap_hash != NULL)
691 {
692 struct elf_link_hash_entry **cur_sym_hashes;
693
694 /* Loop only over the symbols whom been already checked. */
695 for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
696 cur_sym_hashes++)
697 {
698 /* If the current symbol is identical to 'sym_hash', that means
699 the symbol was already adjusted (or at least checked). */
700 if (*cur_sym_hashes == sym_hash)
701 break;
702 }
703 /* Don't adjust the symbol again. */
704 if (cur_sym_hashes < sym_hashes)
705 continue;
706 }
707
708 if ((sym_hash->root.type == bfd_link_hash_defined
709 || sym_hash->root.type == bfd_link_hash_defweak)
710 && sym_hash->root.u.def.section == sec
711 && sym_hash->root.u.def.value > addr
712 && sym_hash->root.u.def.value < toaddr)
713 sym_hash->root.u.def.value -= count;
714 }
715
716 return TRUE;
717 }
718
719 /* This is a version of bfd_generic_get_relocated_section_contents
720 which uses elf32_crx_relocate_section. */
721
722 static bfd_byte *
723 elf32_crx_get_relocated_section_contents (bfd *output_bfd,
724 struct bfd_link_info *link_info,
725 struct bfd_link_order *link_order,
726 bfd_byte *data,
727 bfd_boolean relocatable,
728 asymbol **symbols)
729 {
730 Elf_Internal_Shdr *symtab_hdr;
731 asection *input_section = link_order->u.indirect.section;
732 bfd *input_bfd = input_section->owner;
733 asection **sections = NULL;
734 Elf_Internal_Rela *internal_relocs = NULL;
735 Elf_Internal_Sym *isymbuf = NULL;
736
737 /* We only need to handle the case of relaxing, or of having a
738 particular set of section contents, specially. */
739 if (relocatable
740 || elf_section_data (input_section)->this_hdr.contents == NULL)
741 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
742 link_order, data,
743 relocatable,
744 symbols);
745
746 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
747
748 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
749 (size_t) input_section->size);
750
751 if ((input_section->flags & SEC_RELOC) != 0
752 && input_section->reloc_count > 0)
753 {
754 Elf_Internal_Sym *isym;
755 Elf_Internal_Sym *isymend;
756 asection **secpp;
757 bfd_size_type amt;
758
759 internal_relocs = (_bfd_elf_link_read_relocs
760 (input_bfd, input_section, (PTR) NULL,
761 (Elf_Internal_Rela *) NULL, FALSE));
762 if (internal_relocs == NULL)
763 goto error_return;
764
765 if (symtab_hdr->sh_info != 0)
766 {
767 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
768 if (isymbuf == NULL)
769 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
770 symtab_hdr->sh_info, 0,
771 NULL, NULL, NULL);
772 if (isymbuf == NULL)
773 goto error_return;
774 }
775
776 amt = symtab_hdr->sh_info;
777 amt *= sizeof (asection *);
778 sections = bfd_malloc (amt);
779 if (sections == NULL && amt != 0)
780 goto error_return;
781
782 isymend = isymbuf + symtab_hdr->sh_info;
783 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
784 {
785 asection *isec;
786
787 if (isym->st_shndx == SHN_UNDEF)
788 isec = bfd_und_section_ptr;
789 else if (isym->st_shndx == SHN_ABS)
790 isec = bfd_abs_section_ptr;
791 else if (isym->st_shndx == SHN_COMMON)
792 isec = bfd_com_section_ptr;
793 else
794 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
795
796 *secpp = isec;
797 }
798
799 if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
800 input_section, data, internal_relocs,
801 isymbuf, sections))
802 goto error_return;
803
804 if (sections != NULL)
805 free (sections);
806 if (isymbuf != NULL
807 && symtab_hdr->contents != (unsigned char *) isymbuf)
808 free (isymbuf);
809 if (elf_section_data (input_section)->relocs != internal_relocs)
810 free (internal_relocs);
811 }
812
813 return data;
814
815 error_return:
816 if (sections != NULL)
817 free (sections);
818 if (isymbuf != NULL
819 && symtab_hdr->contents != (unsigned char *) isymbuf)
820 free (isymbuf);
821 if (internal_relocs != NULL
822 && elf_section_data (input_section)->relocs != internal_relocs)
823 free (internal_relocs);
824 return NULL;
825 }
826
827 /* Relocate a CRX ELF section. */
828
829 static bfd_boolean
830 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
831 bfd *input_bfd, asection *input_section,
832 bfd_byte *contents, Elf_Internal_Rela *relocs,
833 Elf_Internal_Sym *local_syms,
834 asection **local_sections)
835 {
836 Elf_Internal_Shdr *symtab_hdr;
837 struct elf_link_hash_entry **sym_hashes;
838 Elf_Internal_Rela *rel, *relend;
839
840 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
841 sym_hashes = elf_sym_hashes (input_bfd);
842
843 rel = relocs;
844 relend = relocs + input_section->reloc_count;
845 for (; rel < relend; rel++)
846 {
847 int r_type;
848 reloc_howto_type *howto;
849 unsigned long r_symndx;
850 Elf_Internal_Sym *sym;
851 asection *sec;
852 struct elf_link_hash_entry *h;
853 bfd_vma relocation;
854 bfd_reloc_status_type r;
855
856 r_symndx = ELF32_R_SYM (rel->r_info);
857 r_type = ELF32_R_TYPE (rel->r_info);
858 howto = crx_elf_howto_table + (r_type);
859
860 h = NULL;
861 sym = NULL;
862 sec = NULL;
863 if (r_symndx < symtab_hdr->sh_info)
864 {
865 sym = local_syms + r_symndx;
866 sec = local_sections[r_symndx];
867 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
868 }
869 else
870 {
871 bfd_boolean unresolved_reloc, warned;
872
873 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
874 r_symndx, symtab_hdr, sym_hashes,
875 h, sec, relocation,
876 unresolved_reloc, warned);
877 }
878
879 if (sec != NULL && elf_discarded_section (sec))
880 {
881 /* For relocs against symbols from removed linkonce sections,
882 or sections discarded by a linker script, we just want the
883 section contents zeroed. Avoid any special processing. */
884 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
885 rel->r_info = 0;
886 rel->r_addend = 0;
887 continue;
888 }
889
890 if (info->relocatable)
891 continue;
892
893 r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
894 input_section,
895 contents, rel->r_offset,
896 relocation, rel->r_addend,
897 info, sec, h == NULL);
898
899 if (r != bfd_reloc_ok)
900 {
901 const char *name;
902 const char *msg = (const char *) 0;
903
904 if (h != NULL)
905 name = h->root.root.string;
906 else
907 {
908 name = (bfd_elf_string_from_elf_section
909 (input_bfd, symtab_hdr->sh_link, sym->st_name));
910 if (name == NULL || *name == '\0')
911 name = bfd_section_name (input_bfd, sec);
912 }
913
914 switch (r)
915 {
916 case bfd_reloc_overflow:
917 if (!((*info->callbacks->reloc_overflow)
918 (info, (h ? &h->root : NULL), name, howto->name,
919 (bfd_vma) 0, input_bfd, input_section,
920 rel->r_offset)))
921 return FALSE;
922 break;
923
924 case bfd_reloc_undefined:
925 if (!((*info->callbacks->undefined_symbol)
926 (info, name, input_bfd, input_section,
927 rel->r_offset, TRUE)))
928 return FALSE;
929 break;
930
931 case bfd_reloc_outofrange:
932 msg = _("internal error: out of range error");
933 goto common_error;
934
935 case bfd_reloc_notsupported:
936 msg = _("internal error: unsupported relocation error");
937 goto common_error;
938
939 case bfd_reloc_dangerous:
940 msg = _("internal error: dangerous error");
941 goto common_error;
942
943 default:
944 msg = _("internal error: unknown error");
945 /* Fall through. */
946
947 common_error:
948 if (!((*info->callbacks->warning)
949 (info, msg, name, input_bfd, input_section,
950 rel->r_offset)))
951 return FALSE;
952 break;
953 }
954 }
955 }
956
957 return TRUE;
958 }
959
960 /* This function handles relaxing for the CRX.
961
962 There's quite a few relaxing opportunites available on the CRX:
963
964 * bal/bcond:32 -> bal/bcond:16 2 bytes
965 * bcond:16 -> bcond:8 2 bytes
966 * cmpbcond:24 -> cmpbcond:8 2 bytes
967 * arithmetic imm32 -> arithmetic imm16 2 bytes
968
969 Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
970
971 static bfd_boolean
972 elf32_crx_relax_section (bfd *abfd, asection *sec,
973 struct bfd_link_info *link_info, bfd_boolean *again)
974 {
975 Elf_Internal_Shdr *symtab_hdr;
976 Elf_Internal_Rela *internal_relocs;
977 Elf_Internal_Rela *irel, *irelend;
978 bfd_byte *contents = NULL;
979 Elf_Internal_Sym *isymbuf = NULL;
980
981 /* Assume nothing changes. */
982 *again = FALSE;
983
984 /* We don't have to do anything for a relocatable link, if
985 this section does not have relocs, or if this is not a
986 code section. */
987 if (link_info->relocatable
988 || (sec->flags & SEC_RELOC) == 0
989 || sec->reloc_count == 0
990 || (sec->flags & SEC_CODE) == 0)
991 return TRUE;
992
993 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
994
995 /* Get a copy of the native relocations. */
996 internal_relocs = (_bfd_elf_link_read_relocs
997 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
998 link_info->keep_memory));
999 if (internal_relocs == NULL)
1000 goto error_return;
1001
1002 /* Walk through them looking for relaxing opportunities. */
1003 irelend = internal_relocs + sec->reloc_count;
1004 for (irel = internal_relocs; irel < irelend; irel++)
1005 {
1006 bfd_vma symval;
1007
1008 /* If this isn't something that can be relaxed, then ignore
1009 this reloc. */
1010 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
1011 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
1012 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
1013 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
1014 continue;
1015
1016 /* Get the section contents if we haven't done so already. */
1017 if (contents == NULL)
1018 {
1019 /* Get cached copy if it exists. */
1020 if (elf_section_data (sec)->this_hdr.contents != NULL)
1021 contents = elf_section_data (sec)->this_hdr.contents;
1022 /* Go get them off disk. */
1023 else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1024 goto error_return;
1025 }
1026
1027 /* Read this BFD's local symbols if we haven't done so already. */
1028 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1029 {
1030 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1031 if (isymbuf == NULL)
1032 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1033 symtab_hdr->sh_info, 0,
1034 NULL, NULL, NULL);
1035 if (isymbuf == NULL)
1036 goto error_return;
1037 }
1038
1039 /* Get the value of the symbol referred to by the reloc. */
1040 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1041 {
1042 /* A local symbol. */
1043 Elf_Internal_Sym *isym;
1044 asection *sym_sec;
1045
1046 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1047 if (isym->st_shndx == SHN_UNDEF)
1048 sym_sec = bfd_und_section_ptr;
1049 else if (isym->st_shndx == SHN_ABS)
1050 sym_sec = bfd_abs_section_ptr;
1051 else if (isym->st_shndx == SHN_COMMON)
1052 sym_sec = bfd_com_section_ptr;
1053 else
1054 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1055 symval = (isym->st_value
1056 + sym_sec->output_section->vma
1057 + sym_sec->output_offset);
1058 }
1059 else
1060 {
1061 unsigned long indx;
1062 struct elf_link_hash_entry *h;
1063
1064 /* An external symbol. */
1065 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1066 h = elf_sym_hashes (abfd)[indx];
1067 BFD_ASSERT (h != NULL);
1068
1069 if (h->root.type != bfd_link_hash_defined
1070 && h->root.type != bfd_link_hash_defweak)
1071 /* This appears to be a reference to an undefined
1072 symbol. Just ignore it--it will be caught by the
1073 regular reloc processing. */
1074 continue;
1075
1076 symval = (h->root.u.def.value
1077 + h->root.u.def.section->output_section->vma
1078 + h->root.u.def.section->output_offset);
1079 }
1080
1081 /* For simplicity of coding, we are going to modify the section
1082 contents, the section relocs, and the BFD symbol table. We
1083 must tell the rest of the code not to free up this
1084 information. It would be possible to instead create a table
1085 of changes which have to be made, as is done in coff-mips.c;
1086 that would be more work, but would require less memory when
1087 the linker is run. */
1088
1089 /* Try to turn a 32bit pc-relative branch/call into
1090 a 16bit pc-relative branch/call. */
1091 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
1092 {
1093 bfd_vma value = symval;
1094
1095 /* Deal with pc-relative gunk. */
1096 value -= (sec->output_section->vma + sec->output_offset);
1097 value -= irel->r_offset;
1098 value += irel->r_addend;
1099
1100 /* See if the value will fit in 16 bits, note the high value is
1101 0xfffe + 2 as the target will be two bytes closer if we are
1102 able to relax. */
1103 if ((long) value < 0x10000 && (long) value > -0x10002)
1104 {
1105 unsigned short code;
1106
1107 /* Get the opcode. */
1108 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1109
1110 /* Verify it's a 'bal'/'bcond' and fix the opcode. */
1111 if ((code & 0xfff0) == 0x3170)
1112 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1113 else if ((code & 0xf0ff) == 0x707f)
1114 bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
1115 else
1116 continue;
1117
1118 /* Note that we've changed the relocs, section contents, etc. */
1119 elf_section_data (sec)->relocs = internal_relocs;
1120 elf_section_data (sec)->this_hdr.contents = contents;
1121 symtab_hdr->contents = (unsigned char *) isymbuf;
1122
1123 /* Fix the relocation's type. */
1124 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1125 R_CRX_REL16);
1126
1127 /* Delete two bytes of data. */
1128 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1129 irel->r_offset + 2, 2))
1130 goto error_return;
1131
1132 /* That will change things, so, we should relax again.
1133 Note that this is not required, and it may be slow. */
1134 *again = TRUE;
1135 }
1136 }
1137
1138 /* Try to turn a 16bit pc-relative branch into an
1139 8bit pc-relative branch. */
1140 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
1141 {
1142 bfd_vma value = symval;
1143
1144 /* Deal with pc-relative gunk. */
1145 value -= (sec->output_section->vma + sec->output_offset);
1146 value -= irel->r_offset;
1147 value += irel->r_addend;
1148
1149 /* See if the value will fit in 8 bits, note the high value is
1150 0xfc + 2 as the target will be two bytes closer if we are
1151 able to relax. */
1152 if ((long) value < 0xfe && (long) value > -0x100)
1153 {
1154 unsigned short code;
1155
1156 /* Get the opcode. */
1157 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1158
1159 /* Verify it's a 'bcond' opcode. */
1160 if ((code & 0xf0ff) != 0x707e)
1161 continue;
1162
1163 /* Note that we've changed the relocs, section contents, etc. */
1164 elf_section_data (sec)->relocs = internal_relocs;
1165 elf_section_data (sec)->this_hdr.contents = contents;
1166 symtab_hdr->contents = (unsigned char *) isymbuf;
1167
1168 /* Fix the relocation's type. */
1169 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1170 R_CRX_REL8);
1171
1172 /* Delete two bytes of data. */
1173 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1174 irel->r_offset + 2, 2))
1175 goto error_return;
1176
1177 /* That will change things, so, we should relax again.
1178 Note that this is not required, and it may be slow. */
1179 *again = TRUE;
1180 }
1181 }
1182
1183 /* Try to turn a 24bit pc-relative cmp&branch into
1184 an 8bit pc-relative cmp&branch. */
1185 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
1186 {
1187 bfd_vma value = symval;
1188
1189 /* Deal with pc-relative gunk. */
1190 value -= (sec->output_section->vma + sec->output_offset);
1191 value -= irel->r_offset;
1192 value += irel->r_addend;
1193
1194 /* See if the value will fit in 8 bits, note the high value is
1195 0x7e + 2 as the target will be two bytes closer if we are
1196 able to relax. */
1197 if ((long) value < 0x100 && (long) value > -0x100)
1198 {
1199 unsigned short code;
1200
1201 /* Get the opcode. */
1202 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1203
1204 /* Verify it's a 'cmp&branch' opcode. */
1205 if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
1206 && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
1207 && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
1208 /* Or a Co-processor branch ('bcop'). */
1209 && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
1210 continue;
1211
1212 /* Note that we've changed the relocs, section contents, etc. */
1213 elf_section_data (sec)->relocs = internal_relocs;
1214 elf_section_data (sec)->this_hdr.contents = contents;
1215 symtab_hdr->contents = (unsigned char *) isymbuf;
1216
1217 /* Fix the opcode. */
1218 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1219
1220 /* Fix the relocation's type. */
1221 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1222 R_CRX_REL8_CMP);
1223
1224 /* Delete two bytes of data. */
1225 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1226 irel->r_offset + 4, 2))
1227 goto error_return;
1228
1229 /* That will change things, so, we should relax again.
1230 Note that this is not required, and it may be slow. */
1231 *again = TRUE;
1232 }
1233 }
1234
1235 /* Try to turn a 32bit immediate address into
1236 a 16bit immediate address. */
1237 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
1238 {
1239 bfd_vma value = symval;
1240
1241 /* See if the value will fit in 16 bits. */
1242 if ((long) value < 0x7fff && (long) value > -0x8000)
1243 {
1244 unsigned short code;
1245
1246 /* Get the opcode. */
1247 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1248
1249 /* Verify it's a 'arithmetic double'. */
1250 if ((code & 0xf0f0) != 0x20f0)
1251 continue;
1252
1253 /* Note that we've changed the relocs, section contents, etc. */
1254 elf_section_data (sec)->relocs = internal_relocs;
1255 elf_section_data (sec)->this_hdr.contents = contents;
1256 symtab_hdr->contents = (unsigned char *) isymbuf;
1257
1258 /* Fix the opcode. */
1259 bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
1260
1261 /* Fix the relocation's type. */
1262 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1263 R_CRX_IMM16);
1264
1265 /* Delete two bytes of data. */
1266 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1267 irel->r_offset + 2, 2))
1268 goto error_return;
1269
1270 /* That will change things, so, we should relax again.
1271 Note that this is not required, and it may be slow. */
1272 *again = TRUE;
1273 }
1274 }
1275 }
1276
1277 if (isymbuf != NULL
1278 && symtab_hdr->contents != (unsigned char *) isymbuf)
1279 {
1280 if (! link_info->keep_memory)
1281 free (isymbuf);
1282 else
1283 {
1284 /* Cache the symbols for elf_link_input_bfd. */
1285 symtab_hdr->contents = (unsigned char *) isymbuf;
1286 }
1287 }
1288
1289 if (contents != NULL
1290 && elf_section_data (sec)->this_hdr.contents != contents)
1291 {
1292 if (! link_info->keep_memory)
1293 free (contents);
1294 else
1295 {
1296 /* Cache the section contents for elf_link_input_bfd. */
1297 elf_section_data (sec)->this_hdr.contents = contents;
1298 }
1299 }
1300
1301 if (internal_relocs != NULL
1302 && elf_section_data (sec)->relocs != internal_relocs)
1303 free (internal_relocs);
1304
1305 return TRUE;
1306
1307 error_return:
1308 if (isymbuf != NULL
1309 && symtab_hdr->contents != (unsigned char *) isymbuf)
1310 free (isymbuf);
1311 if (contents != NULL
1312 && elf_section_data (sec)->this_hdr.contents != contents)
1313 free (contents);
1314 if (internal_relocs != NULL
1315 && elf_section_data (sec)->relocs != internal_relocs)
1316 free (internal_relocs);
1317
1318 return FALSE;
1319 }
1320
1321 /* Definitions for setting CRX target vector. */
1322 #define TARGET_LITTLE_SYM bfd_elf32_crx_vec
1323 #define TARGET_LITTLE_NAME "elf32-crx"
1324 #define ELF_ARCH bfd_arch_crx
1325 #define ELF_MACHINE_CODE EM_CRX
1326 #define ELF_MAXPAGESIZE 0x1
1327 #define elf_symbol_leading_char '_'
1328
1329 #define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup
1330 #define bfd_elf32_bfd_reloc_name_lookup \
1331 elf_crx_reloc_name_lookup
1332 #define elf_info_to_howto elf_crx_info_to_howto
1333 #define elf_info_to_howto_rel 0
1334 #define elf_backend_relocate_section elf32_crx_relocate_section
1335 #define bfd_elf32_bfd_relax_section elf32_crx_relax_section
1336 #define bfd_elf32_bfd_get_relocated_section_contents \
1337 elf32_crx_get_relocated_section_contents
1338 #define elf_backend_can_gc_sections 1
1339 #define elf_backend_rela_normal 1
1340
1341 #include "elf32-target.h"
This page took 0.091581 seconds and 5 git commands to generate.