opcodes/arc: Support dmb instruction with no operands
[external/binutils.git] / bfd / elf32-crx.c
1 /* BFD back-end for National Semiconductor's CRX ELF
2    Copyright (C) 2004-2015 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          3,                     /* size */
86          0,                     /* bitsize */
87          FALSE,                 /* pc_relative */
88          0,                     /* bitpos */
89          complain_overflow_dont,/* complain_on_overflow */
90          bfd_elf_generic_reloc, /* special_function */
91          "R_CRX_NONE",          /* name */
92          FALSE,                 /* partial_inplace */
93          0,                     /* src_mask */
94          0,                     /* dst_mask */
95          FALSE),                /* pcrel_offset */
96
97   HOWTO (R_CRX_REL4,            /* type */
98          1,                     /* rightshift */
99          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   if (r_type >= R_CRX_MAX)
427     {
428       (*_bfd_error_handler) (_("%B: unrecognised CRX reloc number: %d"),
429                              abfd, r_type);
430       bfd_set_error (bfd_error_bad_value);
431       r_type = R_CRX_NONE;
432     }
433   cache_ptr->howto = &crx_elf_howto_table[r_type];
434 }
435
436 /* Perform a relocation as part of a final link.  */
437
438 static bfd_reloc_status_type
439 crx_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
480      case R_CRX_SWITCH8:
481      case R_CRX_SWITCH16:
482      case R_CRX_SWITCH32:
483        /* We only care about the addend, where the difference between
484           expressions is kept.  */
485        Rvalue = 0;
486
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
564        if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
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
592 static bfd_boolean
593 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
594                               asection *sec, bfd_vma addr, int count)
595 {
596   Elf_Internal_Shdr *symtab_hdr;
597   unsigned int sec_shndx;
598   bfd_byte *contents;
599   Elf_Internal_Rela *irel, *irelend;
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;
605   struct elf_link_hash_entry **start_hashes;
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
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)
639         {
640           /* Adjust the addend of SWITCH relocations in this section,
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         }
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);
678   sym_hashes = start_hashes = elf_sym_hashes (abfd);
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
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.
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;
695
696           /* Loop only over the symbols whom been already checked.  */
697           for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
698                cur_sym_hashes++)
699             {
700               /* If the current symbol is identical to 'sym_hash', that means
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
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
724 static bfd_byte *
725 elf32_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
762                          (input_bfd, input_section, NULL,
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
831 static bfd_boolean
832 elf32_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
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         {
873           bfd_boolean unresolved_reloc, warned, ignored;
874
875           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
876                                    r_symndx, symtab_hdr, sym_hashes,
877                                    h, sec, relocation,
878                                    unresolved_reloc, warned, ignored);
879         }
880
881       if (sec != NULL && discarded_section (sec))
882         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
883                                          rel, 1, relend, howto, 0, contents);
884
885       if (bfd_link_relocatable (info))
886         continue;
887
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)
913                      (info, (h ? &h->root : NULL), name, howto->name,
914                       (bfd_vma) 0, input_bfd, input_section,
915                       rel->r_offset)))
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
966 static bfd_boolean
967 elf32_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 (bfd_link_relocatable (link_info)
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
992                      (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
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.  */
1123               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
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.  */
1168               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
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
1202                && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
1203                /* Or a Co-processor branch ('bcop').  */
1204                && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
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.  */
1220               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
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.  */
1261               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
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
1316 /* Definitions for setting CRX target vector.  */
1317 #define TARGET_LITTLE_SYM               crx_elf32_vec
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
1325 #define bfd_elf32_bfd_reloc_name_lookup \
1326                                         elf_crx_reloc_name_lookup
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
1333 #define elf_backend_can_gc_sections     1
1334 #define elf_backend_rela_normal         1
1335
1336 #include "elf32-target.h"