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