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