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