fix set but unused variable warnings
[external/binutils.git] / bfd / elf32-crx.c
1 /* BFD back-end for National Semiconductor's CRX ELF
2    Copyright 2004, 2005, 2006, 2007, 2009, 2010
3    Free Software Foundation, Inc.
4    Written by Tomer Levi, NSC, Israel.
5
6    This file is part of BFD, the Binary File Descriptor library.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "bfdlink.h"
26 #include "libbfd.h"
27 #include "elf-bfd.h"
28 #include "elf/crx.h"
29
30 static reloc_howto_type *elf_crx_reloc_type_lookup
31   (bfd *, bfd_reloc_code_real_type);
32 static void elf_crx_info_to_howto
33   (bfd *, arelent *, Elf_Internal_Rela *);
34 static bfd_boolean elf32_crx_relax_delete_bytes
35   (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
36 static bfd_reloc_status_type crx_elf_final_link_relocate
37   (reloc_howto_type *, bfd *, bfd *, asection *,
38    bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
39    struct bfd_link_info *, asection *, int);
40 static bfd_boolean elf32_crx_relocate_section
41   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
42    Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
43 static bfd_boolean elf32_crx_relax_section
44   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
45 static bfd_byte * elf32_crx_get_relocated_section_contents
46   (bfd *, struct bfd_link_info *, struct bfd_link_order *,
47    bfd_byte *, bfd_boolean, asymbol **);
48
49 /* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type.  */
50
51 struct crx_reloc_map
52 {
53   bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum.  */
54   unsigned short crx_reloc_type;           /* CRX relocation type.  */
55 };
56
57 static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
58 {
59   {BFD_RELOC_NONE,          R_CRX_NONE},
60   {BFD_RELOC_CRX_REL4,      R_CRX_REL4},
61   {BFD_RELOC_CRX_REL8,      R_CRX_REL8},
62   {BFD_RELOC_CRX_REL8_CMP,  R_CRX_REL8_CMP},
63   {BFD_RELOC_CRX_REL16,     R_CRX_REL16},
64   {BFD_RELOC_CRX_REL24,     R_CRX_REL24},
65   {BFD_RELOC_CRX_REL32,     R_CRX_REL32},
66   {BFD_RELOC_CRX_REGREL12,  R_CRX_REGREL12},
67   {BFD_RELOC_CRX_REGREL22,  R_CRX_REGREL22},
68   {BFD_RELOC_CRX_REGREL28,  R_CRX_REGREL28},
69   {BFD_RELOC_CRX_REGREL32,  R_CRX_REGREL32},
70   {BFD_RELOC_CRX_ABS16,     R_CRX_ABS16},
71   {BFD_RELOC_CRX_ABS32,     R_CRX_ABS32},
72   {BFD_RELOC_CRX_NUM8,      R_CRX_NUM8},
73   {BFD_RELOC_CRX_NUM16,     R_CRX_NUM16},
74   {BFD_RELOC_CRX_NUM32,     R_CRX_NUM32},
75   {BFD_RELOC_CRX_IMM16,     R_CRX_IMM16},
76   {BFD_RELOC_CRX_IMM32,     R_CRX_IMM32},
77   {BFD_RELOC_CRX_SWITCH8,   R_CRX_SWITCH8},
78   {BFD_RELOC_CRX_SWITCH16,  R_CRX_SWITCH16},
79   {BFD_RELOC_CRX_SWITCH32,  R_CRX_SWITCH32}
80 };
81
82 static reloc_howto_type crx_elf_howto_table[] =
83 {
84   HOWTO (R_CRX_NONE,            /* type */
85          0,                     /* rightshift */
86          2,                     /* size */
87          32,                    /* bitsize */
88          FALSE,                 /* pc_relative */
89          0,                     /* bitpos */
90          complain_overflow_dont,/* complain_on_overflow */
91          bfd_elf_generic_reloc, /* special_function */
92          "R_CRX_NONE",          /* name */
93          FALSE,                 /* partial_inplace */
94          0,                     /* src_mask */
95          0,                     /* dst_mask */
96          FALSE),                /* pcrel_offset */
97
98   HOWTO (R_CRX_REL4,            /* type */
99          1,                     /* rightshift */
100          0,                     /* size */
101          4,                     /* bitsize */
102          TRUE,                  /* pc_relative */
103          0,                     /* bitpos */
104          complain_overflow_bitfield,/* complain_on_overflow */
105          bfd_elf_generic_reloc, /* special_function */
106          "R_CRX_REL4",          /* name */
107          FALSE,                 /* partial_inplace */
108          0x0,                   /* src_mask */
109          0xf,                   /* dst_mask */
110          FALSE),                /* pcrel_offset */
111
112   HOWTO (R_CRX_REL8,            /* type */
113          1,                     /* rightshift */
114          0,                     /* size */
115          8,                     /* bitsize */
116          TRUE,                  /* pc_relative */
117          0,                     /* bitpos */
118          complain_overflow_bitfield,/* complain_on_overflow */
119          bfd_elf_generic_reloc, /* special_function */
120          "R_CRX_REL8",          /* name */
121          FALSE,                 /* partial_inplace */
122          0x0,                   /* src_mask */
123          0xff,                  /* dst_mask */
124          FALSE),                /* pcrel_offset */
125
126   HOWTO (R_CRX_REL8_CMP,        /* type */
127          1,                     /* rightshift */
128          0,                     /* size */
129          8,                     /* bitsize */
130          TRUE,                  /* pc_relative */
131          0,                     /* bitpos */
132          complain_overflow_bitfield,/* complain_on_overflow */
133          bfd_elf_generic_reloc, /* special_function */
134          "R_CRX_REL8_CMP",      /* name */
135          FALSE,                 /* partial_inplace */
136          0x0,                   /* src_mask */
137          0xff,                  /* dst_mask */
138          FALSE),                /* pcrel_offset */
139
140   HOWTO (R_CRX_REL16,           /* type */
141          1,                     /* rightshift */
142          1,                     /* size */
143          16,                    /* bitsize */
144          TRUE,                  /* pc_relative */
145          0,                     /* bitpos */
146          complain_overflow_bitfield,/* complain_on_overflow */
147          bfd_elf_generic_reloc, /* special_function */
148          "R_CRX_REL16",         /* name */
149          FALSE,                 /* partial_inplace */
150          0x0,                   /* src_mask */
151          0xffff,                /* dst_mask */
152          FALSE),                /* pcrel_offset */
153
154   HOWTO (R_CRX_REL24,           /* type */
155          1,                     /* rightshift */
156          2,                     /* size */
157          24,                    /* bitsize */
158          TRUE,                  /* pc_relative */
159          0,                     /* bitpos */
160          complain_overflow_bitfield,/* complain_on_overflow */
161          bfd_elf_generic_reloc, /* special_function */
162          "R_CRX_REL24",         /* name */
163          FALSE,                 /* partial_inplace */
164          0x0,                   /* src_mask */
165          0xffffff,              /* dst_mask */
166          FALSE),                /* pcrel_offset */
167
168   HOWTO (R_CRX_REL32,           /* type */
169          1,                     /* rightshift */
170          2,                     /* size */
171          32,                    /* bitsize */
172          TRUE,                  /* pc_relative */
173          0,                     /* bitpos */
174          complain_overflow_bitfield,/* complain_on_overflow */
175          bfd_elf_generic_reloc, /* special_function */
176          "R_CRX_REL32",         /* name */
177          FALSE,                 /* partial_inplace */
178          0x0,                   /* src_mask */
179          0xffffffff,            /* dst_mask */
180          FALSE),                /* pcrel_offset */
181
182   HOWTO (R_CRX_REGREL12,        /* type */
183          0,                     /* rightshift */
184          1,                     /* size */
185          12,                    /* bitsize */
186          FALSE,                 /* pc_relative */
187          0,                     /* bitpos */
188          complain_overflow_bitfield,/* complain_on_overflow */
189          bfd_elf_generic_reloc, /* special_function */
190          "R_CRX_REGREL12",      /* name */
191          FALSE,                 /* partial_inplace */
192          0x0,                   /* src_mask */
193          0xfff,                 /* dst_mask */
194          FALSE),                /* pcrel_offset */
195
196   HOWTO (R_CRX_REGREL22,        /* type */
197          0,                     /* rightshift */
198          2,                     /* size */
199          22,                    /* bitsize */
200          FALSE,                 /* pc_relative */
201          0,                     /* bitpos */
202          complain_overflow_bitfield,/* complain_on_overflow */
203          bfd_elf_generic_reloc, /* special_function */
204          "R_CRX_REGREL22",      /* name */
205          FALSE,                 /* partial_inplace */
206          0x0,                   /* src_mask */
207          0x3fffff,              /* dst_mask */
208          FALSE),                /* pcrel_offset */
209
210   HOWTO (R_CRX_REGREL28,        /* type */
211          0,                     /* rightshift */
212          2,                     /* size */
213          28,                    /* bitsize */
214          FALSE,                 /* pc_relative */
215          0,                     /* bitpos */
216          complain_overflow_bitfield,/* complain_on_overflow */
217          bfd_elf_generic_reloc, /* special_function */
218          "R_CRX_REGREL28",      /* name */
219          FALSE,                 /* partial_inplace */
220          0x0,                   /* src_mask */
221          0xfffffff,             /* dst_mask */
222          FALSE),                /* pcrel_offset */
223
224   HOWTO (R_CRX_REGREL32,        /* type */
225          0,                     /* rightshift */
226          2,                     /* size */
227          32,                    /* bitsize */
228          FALSE,                 /* pc_relative */
229          0,                     /* bitpos */
230          complain_overflow_bitfield,/* complain_on_overflow */
231          bfd_elf_generic_reloc, /* special_function */
232          "R_CRX_REGREL32",      /* name */
233          FALSE,                 /* partial_inplace */
234          0x0,                   /* src_mask */
235          0xffffffff,            /* dst_mask */
236          FALSE),                /* pcrel_offset */
237
238   HOWTO (R_CRX_ABS16,           /* type */
239          0,                     /* rightshift */
240          1,                     /* size */
241          16,                    /* bitsize */
242          FALSE,                 /* pc_relative */
243          0,                     /* bitpos */
244          complain_overflow_bitfield,/* complain_on_overflow */
245          bfd_elf_generic_reloc, /* special_function */
246          "R_CRX_ABS16",         /* name */
247          FALSE,                 /* partial_inplace */
248          0x0,                   /* src_mask */
249          0xffff,                /* dst_mask */
250          FALSE),                /* pcrel_offset */
251
252   HOWTO (R_CRX_ABS32,           /* type */
253          0,                     /* rightshift */
254          2,                     /* size */
255          32,                    /* bitsize */
256          FALSE,                 /* pc_relative */
257          0,                     /* bitpos */
258          complain_overflow_bitfield,/* complain_on_overflow */
259          bfd_elf_generic_reloc, /* special_function */
260          "R_CRX_ABS32",         /* name */
261          FALSE,                 /* partial_inplace */
262          0x0,                   /* src_mask */
263          0xffffffff,            /* dst_mask */
264          FALSE),                /* pcrel_offset */
265
266   HOWTO (R_CRX_NUM8,            /* type */
267          0,                     /* rightshift */
268          0,                     /* size */
269          8,                     /* bitsize */
270          FALSE,                 /* pc_relative */
271          0,                     /* bitpos */
272          complain_overflow_bitfield,/* complain_on_overflow */
273          bfd_elf_generic_reloc, /* special_function */
274          "R_CRX_NUM8",          /* name */
275          FALSE,                 /* partial_inplace */
276          0x0,                   /* src_mask */
277          0xff,                  /* dst_mask */
278          FALSE),                /* pcrel_offset */
279
280   HOWTO (R_CRX_NUM16,           /* type */
281          0,                     /* rightshift */
282          1,                     /* size */
283          16,                    /* bitsize */
284          FALSE,                 /* pc_relative */
285          0,                     /* bitpos */
286          complain_overflow_bitfield,/* complain_on_overflow */
287          bfd_elf_generic_reloc, /* special_function */
288          "R_CRX_NUM16",         /* name */
289          FALSE,                 /* partial_inplace */
290          0x0,                   /* src_mask */
291          0xffff,                /* dst_mask */
292          FALSE),                /* pcrel_offset */
293
294   HOWTO (R_CRX_NUM32,           /* type */
295          0,                     /* rightshift */
296          2,                     /* size */
297          32,                    /* bitsize */
298          FALSE,                 /* pc_relative */
299          0,                     /* bitpos */
300          complain_overflow_bitfield,/* complain_on_overflow */
301          bfd_elf_generic_reloc, /* special_function */
302          "R_CRX_NUM32",         /* name */
303          FALSE,                 /* partial_inplace */
304          0x0,                   /* src_mask */
305          0xffffffff,            /* dst_mask */
306          FALSE),                /* pcrel_offset */
307
308   HOWTO (R_CRX_IMM16,           /* type */
309          0,                     /* rightshift */
310          1,                     /* size */
311          16,                    /* bitsize */
312          FALSE,                 /* pc_relative */
313          0,                     /* bitpos */
314          complain_overflow_bitfield,/* complain_on_overflow */
315          bfd_elf_generic_reloc, /* special_function */
316          "R_CRX_IMM16",         /* name */
317          FALSE,                 /* partial_inplace */
318          0x0,                   /* src_mask */
319          0xffff,                /* dst_mask */
320          FALSE),                /* pcrel_offset */
321
322   HOWTO (R_CRX_IMM32,           /* type */
323          0,                     /* rightshift */
324          2,                     /* size */
325          32,                    /* bitsize */
326          FALSE,                 /* pc_relative */
327          0,                     /* bitpos */
328          complain_overflow_bitfield,/* complain_on_overflow */
329          bfd_elf_generic_reloc, /* special_function */
330          "R_CRX_IMM32",         /* name */
331          FALSE,                 /* partial_inplace */
332          0x0,                   /* src_mask */
333          0xffffffff,            /* dst_mask */
334          FALSE),                /* pcrel_offset */
335  
336   /* An 8 bit switch table entry.  This is generated for an expression
337      such as ``.byte L1 - L2''.  The offset holds the difference
338      between the reloc address and L2.  */
339   HOWTO (R_CRX_SWITCH8,         /* type */
340          0,                     /* rightshift */
341          0,                     /* size (0 = byte, 1 = short, 2 = long) */
342          8,                     /* bitsize */
343          FALSE,                 /* pc_relative */
344          0,                     /* bitpos */
345          complain_overflow_unsigned, /* complain_on_overflow */
346          bfd_elf_generic_reloc, /* special_function */
347          "R_CRX_SWITCH8",       /* name */
348          FALSE,                 /* partial_inplace */
349          0x0,                   /* src_mask */
350          0xff,                  /* dst_mask */
351          TRUE),                 /* pcrel_offset */
352
353   /* A 16 bit switch table entry.  This is generated for an expression
354      such as ``.word L1 - L2''.  The offset holds the difference
355      between the reloc address and L2.  */
356   HOWTO (R_CRX_SWITCH16,        /* type */
357          0,                     /* rightshift */
358          1,                     /* size (0 = byte, 1 = short, 2 = long) */
359          16,                    /* bitsize */
360          FALSE,                 /* pc_relative */
361          0,                     /* bitpos */
362          complain_overflow_unsigned, /* complain_on_overflow */
363          bfd_elf_generic_reloc, /* special_function */
364          "R_CRX_SWITCH16",      /* name */
365          FALSE,                 /* partial_inplace */
366          0x0,                   /* src_mask */
367          0xffff,                /* dst_mask */
368          TRUE),                 /* pcrel_offset */
369
370   /* A 32 bit switch table entry.  This is generated for an expression
371      such as ``.long L1 - L2''.  The offset holds the difference
372      between the reloc address and L2.  */
373   HOWTO (R_CRX_SWITCH32,        /* type */
374          0,                     /* rightshift */
375          2,                     /* size (0 = byte, 1 = short, 2 = long) */
376          32,                    /* bitsize */
377          FALSE,                 /* pc_relative */
378          0,                     /* bitpos */
379          complain_overflow_unsigned, /* complain_on_overflow */
380          bfd_elf_generic_reloc, /* special_function */
381          "R_CRX_SWITCH32",      /* name */
382          FALSE,                 /* partial_inplace */
383          0x0,                   /* src_mask */
384          0xffffffff,            /* dst_mask */
385          TRUE)                  /* pcrel_offset */
386 };
387
388 /* Retrieve a howto ptr using a BFD reloc_code.  */
389
390 static reloc_howto_type *
391 elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
392                            bfd_reloc_code_real_type code)
393 {
394   unsigned int i;
395
396   for (i = 0; i < R_CRX_MAX; i++)
397     if (code == crx_reloc_map[i].bfd_reloc_enum)
398       return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
399
400   printf ("This relocation Type is not supported -0x%x\n", code);
401   return 0;
402 }
403
404 static reloc_howto_type *
405 elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
406                            const char *r_name)
407 {
408   unsigned int i;
409
410   for (i = 0;
411        i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]);
412        i++)
413     if (crx_elf_howto_table[i].name != NULL
414         && strcasecmp (crx_elf_howto_table[i].name, r_name) == 0)
415       return &crx_elf_howto_table[i];
416
417   return NULL;
418 }
419
420 /* Retrieve a howto ptr using an internal relocation entry.  */
421
422 static void
423 elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
424                        Elf_Internal_Rela *dst)
425 {
426   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
427   BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
428   cache_ptr->howto = &crx_elf_howto_table[r_type];
429 }
430
431 /* Perform a relocation as part of a final link.  */
432
433 static bfd_reloc_status_type
434 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
435                              bfd *output_bfd ATTRIBUTE_UNUSED,
436                              asection *input_section, bfd_byte *contents,
437                              bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
438                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
439                              asection *sec ATTRIBUTE_UNUSED,
440                              int is_local ATTRIBUTE_UNUSED)
441 {
442   unsigned short r_type = howto->type;
443   bfd_byte *hit_data = contents + offset;
444   bfd_vma reloc_bits, check;
445
446   switch (r_type)
447     {
448      case R_CRX_IMM16:
449      case R_CRX_IMM32:
450      case R_CRX_ABS16:
451      case R_CRX_ABS32:
452      case R_CRX_REL8_CMP:
453      case R_CRX_REL16:
454      case R_CRX_REL24:
455      case R_CRX_REL32:
456      case R_CRX_REGREL12:
457      case R_CRX_REGREL22:
458      case R_CRX_REGREL28:
459      case R_CRX_REGREL32:
460        /* 'hit_data' is relative to the start of the instruction, not the
461           relocation offset. Advance it to account for the exact offset.  */
462        hit_data += 2;
463        break;
464
465      case R_CRX_REL4:
466        /* This relocation type is used only in 'Branch if Equal to 0'
467           instructions and requires special handling.  */
468        Rvalue -= 1;
469        break;
470
471      case R_CRX_NONE:
472        return bfd_reloc_ok;
473        break;
474
475      case R_CRX_SWITCH8:
476      case R_CRX_SWITCH16:
477      case R_CRX_SWITCH32:
478        /* We only care about the addend, where the difference between 
479           expressions is kept.  */
480        Rvalue = 0;
481        
482      default:
483        break;
484     }
485
486   if (howto->pc_relative)
487     {
488       /* Subtract the address of the section containing the location.  */
489       Rvalue -= (input_section->output_section->vma
490                  + input_section->output_offset);
491       /* Subtract the position of the location within the section.  */
492       Rvalue -= offset;
493     }
494
495   /* Add in supplied addend.  */
496   Rvalue += addend;
497
498   /* Complain if the bitfield overflows, whether it is considered
499      as signed or unsigned.  */
500   check = Rvalue >> howto->rightshift;
501
502   /* Assumes two's complement.  This expression avoids
503      overflow if howto->bitsize is the number of bits in
504      bfd_vma.  */
505   reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
506
507   if (((bfd_vma) check & ~reloc_bits) != 0
508       && (((bfd_vma) check & ~reloc_bits)
509           != (-(bfd_vma) 1 & ~reloc_bits)))
510     {
511       /* The above right shift is incorrect for a signed
512          value.  See if turning on the upper bits fixes the
513          overflow.  */
514       if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
515         {
516           check |= ((bfd_vma) - 1
517                     & ~((bfd_vma) - 1
518                         >> howto->rightshift));
519           if (((bfd_vma) check & ~reloc_bits)
520               != (-(bfd_vma) 1 & ~reloc_bits))
521             return bfd_reloc_overflow;
522         }
523       else
524         return bfd_reloc_overflow;
525     }
526
527   /* Drop unwanted bits from the value we are relocating to.  */
528   Rvalue >>= (bfd_vma) howto->rightshift;
529
530   /* Apply dst_mask to select only relocatable part of the insn.  */
531   Rvalue &= howto->dst_mask;
532
533   switch (howto->size)
534     {
535      case 0:
536        if (r_type == R_CRX_REL4)
537          {
538            Rvalue <<= 4;
539            Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
540          }
541
542        bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
543        break;
544
545      case 1:
546        if (r_type == R_CRX_REGREL12)
547          Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
548
549        bfd_put_16 (input_bfd, Rvalue, hit_data);
550        break;
551
552      case 2:
553        if (r_type == R_CRX_REL24
554            || r_type == R_CRX_REGREL22
555            || r_type == R_CRX_REGREL28)
556          Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
557                       bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
558
559        if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
560          /* Relocation on DATA is purely little-endian, that is, for a
561             multi-byte datum, the lowest address in memory contains the
562             little end of the datum, that is, the least significant byte.
563             Therefore we use BFD's byte Putting functions.  */
564          bfd_put_32 (input_bfd, Rvalue, hit_data);
565        else
566          /* Relocation on INSTRUCTIONS is different : Instructions are
567             word-addressable, that is, each word itself is arranged according
568             to little-endian convention, whereas the words are arranged with
569             respect to one another in BIG ENDIAN fashion.
570             When there is an immediate value that spans a word boundary, it is
571             split in a big-endian way with respect to the words.  */
572          {
573            bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
574            bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
575          }
576      break;
577
578      default:
579        return bfd_reloc_notsupported;
580     }
581
582   return bfd_reloc_ok;
583 }
584
585 /* Delete some bytes from a section while relaxing.  */
586
587 static bfd_boolean
588 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd, 
589                               asection *sec, bfd_vma addr, int count)
590 {
591   Elf_Internal_Shdr *symtab_hdr;
592   unsigned int sec_shndx;
593   bfd_byte *contents;
594   Elf_Internal_Rela *irel, *irelend;
595   bfd_vma toaddr;
596   Elf_Internal_Sym *isym;
597   Elf_Internal_Sym *isymend;
598   struct elf_link_hash_entry **sym_hashes;
599   struct elf_link_hash_entry **end_hashes;
600   struct elf_link_hash_entry **start_hashes;
601   unsigned int symcount;
602
603   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
604
605   contents = elf_section_data (sec)->this_hdr.contents;
606
607   toaddr = sec->size;
608
609   irel = elf_section_data (sec)->relocs;
610   irelend = irel + sec->reloc_count;
611
612   /* Actually delete the bytes.  */
613   memmove (contents + addr, contents + addr + count,
614            (size_t) (toaddr - addr - count));
615   sec->size -= count;
616
617   /* Adjust all the relocs.  */
618   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
619     {
620       /* Get the new reloc address.  */
621       if ((irel->r_offset > addr
622            && irel->r_offset < toaddr))
623         irel->r_offset -= count;
624     }
625
626   /* Adjust the local symbols defined in this section.  */
627   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
628   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
629   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
630     {
631       if (isym->st_shndx == sec_shndx
632           && isym->st_value > addr
633           && isym->st_value < toaddr)
634         {
635           /* Adjust the addend of SWITCH relocations in this section, 
636              which reference this local symbol.  */
637           for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
638             {
639               unsigned long r_symndx;
640               Elf_Internal_Sym *rsym;
641               bfd_vma addsym, subsym;
642
643               /* Skip if not a SWITCH relocation.  */
644               if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
645                   && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
646                   && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
647                   continue;
648
649               r_symndx = ELF32_R_SYM (irel->r_info);
650               rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
651
652               /* Skip if not the local adjusted symbol.  */
653               if (rsym != isym)
654                 continue;
655
656               addsym = isym->st_value;
657               subsym = addsym - irel->r_addend;
658
659               /* Fix the addend only when -->> (addsym > addr >= subsym).  */
660               if (subsym <= addr)
661                 irel->r_addend -= count;
662               else
663                 continue;
664             }
665
666           isym->st_value -= count;
667         }
668     }
669
670   /* Now adjust the global symbols defined in this section.  */
671   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
672               - symtab_hdr->sh_info);
673   sym_hashes = start_hashes = elf_sym_hashes (abfd);
674   end_hashes = sym_hashes + symcount;
675
676   for (; sym_hashes < end_hashes; sym_hashes++)
677     {
678       struct elf_link_hash_entry *sym_hash = *sym_hashes;
679
680       /* The '--wrap SYMBOL' option is causing a pain when the object file, 
681          containing the definition of __wrap_SYMBOL, includes a direct 
682          call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 
683          the same symbol (which is __wrap_SYMBOL), but still exist as two 
684          different symbols in 'sym_hashes', we don't want to adjust 
685          the global symbol __wrap_SYMBOL twice.  
686          This check is only relevant when symbols are being wrapped.  */
687       if (link_info->wrap_hash != NULL)
688         {
689           struct elf_link_hash_entry **cur_sym_hashes;
690           
691           /* Loop only over the symbols whom been already checked.  */
692           for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 
693                cur_sym_hashes++)
694             {
695               /* If the current symbol is identical to 'sym_hash', that means 
696                  the symbol was already adjusted (or at least checked).  */
697               if (*cur_sym_hashes == sym_hash)
698                 break;
699             }
700           /* Don't adjust the symbol again.  */
701           if (cur_sym_hashes < sym_hashes)
702             continue;
703         }
704
705       if ((sym_hash->root.type == bfd_link_hash_defined
706            || sym_hash->root.type == bfd_link_hash_defweak)
707           && sym_hash->root.u.def.section == sec
708           && sym_hash->root.u.def.value > addr
709           && sym_hash->root.u.def.value < toaddr)
710         sym_hash->root.u.def.value -= count;
711     }
712
713   return TRUE;
714 }
715
716 /* This is a version of bfd_generic_get_relocated_section_contents
717    which uses elf32_crx_relocate_section.  */
718
719 static bfd_byte *
720 elf32_crx_get_relocated_section_contents (bfd *output_bfd,
721                                           struct bfd_link_info *link_info,
722                                           struct bfd_link_order *link_order,
723                                           bfd_byte *data,
724                                           bfd_boolean relocatable,
725                                           asymbol **symbols)
726 {
727   Elf_Internal_Shdr *symtab_hdr;
728   asection *input_section = link_order->u.indirect.section;
729   bfd *input_bfd = input_section->owner;
730   asection **sections = NULL;
731   Elf_Internal_Rela *internal_relocs = NULL;
732   Elf_Internal_Sym *isymbuf = NULL;
733
734   /* We only need to handle the case of relaxing, or of having a
735      particular set of section contents, specially.  */
736   if (relocatable
737       || elf_section_data (input_section)->this_hdr.contents == NULL)
738     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
739                                                        link_order, data,
740                                                        relocatable,
741                                                        symbols);
742
743   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
744
745   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
746           (size_t) input_section->size);
747
748   if ((input_section->flags & SEC_RELOC) != 0
749       && input_section->reloc_count > 0)
750     {
751       Elf_Internal_Sym *isym;
752       Elf_Internal_Sym *isymend;
753       asection **secpp;
754       bfd_size_type amt;
755
756       internal_relocs = (_bfd_elf_link_read_relocs
757                          (input_bfd, input_section, (PTR) NULL,
758                           (Elf_Internal_Rela *) NULL, FALSE));
759       if (internal_relocs == NULL)
760         goto error_return;
761
762       if (symtab_hdr->sh_info != 0)
763         {
764           isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
765           if (isymbuf == NULL)
766             isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
767                                             symtab_hdr->sh_info, 0,
768                                             NULL, NULL, NULL);
769           if (isymbuf == NULL)
770             goto error_return;
771         }
772
773       amt = symtab_hdr->sh_info;
774       amt *= sizeof (asection *);
775       sections = bfd_malloc (amt);
776       if (sections == NULL && amt != 0)
777         goto error_return;
778
779       isymend = isymbuf + symtab_hdr->sh_info;
780       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
781         {
782           asection *isec;
783
784           if (isym->st_shndx == SHN_UNDEF)
785             isec = bfd_und_section_ptr;
786           else if (isym->st_shndx == SHN_ABS)
787             isec = bfd_abs_section_ptr;
788           else if (isym->st_shndx == SHN_COMMON)
789             isec = bfd_com_section_ptr;
790           else
791             isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
792
793           *secpp = isec;
794         }
795
796       if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
797                                      input_section, data, internal_relocs,
798                                      isymbuf, sections))
799         goto error_return;
800
801       if (sections != NULL)
802         free (sections);
803       if (isymbuf != NULL
804           && symtab_hdr->contents != (unsigned char *) isymbuf)
805         free (isymbuf);
806       if (elf_section_data (input_section)->relocs != internal_relocs)
807         free (internal_relocs);
808     }
809
810   return data;
811
812  error_return:
813   if (sections != NULL)
814     free (sections);
815   if (isymbuf != NULL
816       && symtab_hdr->contents != (unsigned char *) isymbuf)
817     free (isymbuf);
818   if (internal_relocs != NULL
819       && elf_section_data (input_section)->relocs != internal_relocs)
820     free (internal_relocs);
821   return NULL;
822 }
823
824 /* Relocate a CRX ELF section.  */
825
826 static bfd_boolean
827 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
828                             bfd *input_bfd, asection *input_section,
829                             bfd_byte *contents, Elf_Internal_Rela *relocs,
830                             Elf_Internal_Sym *local_syms,
831                             asection **local_sections)
832 {
833   Elf_Internal_Shdr *symtab_hdr;
834   struct elf_link_hash_entry **sym_hashes;
835   Elf_Internal_Rela *rel, *relend;
836
837   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
838   sym_hashes = elf_sym_hashes (input_bfd);
839
840   rel = relocs;
841   relend = relocs + input_section->reloc_count;
842   for (; rel < relend; rel++)
843     {
844       int r_type;
845       reloc_howto_type *howto;
846       unsigned long r_symndx;
847       Elf_Internal_Sym *sym;
848       asection *sec;
849       struct elf_link_hash_entry *h;
850       bfd_vma relocation;
851       bfd_reloc_status_type r;
852
853       r_symndx = ELF32_R_SYM (rel->r_info);
854       r_type = ELF32_R_TYPE (rel->r_info);
855       howto = crx_elf_howto_table + (r_type);
856
857       h = NULL;
858       sym = NULL;
859       sec = NULL;
860       if (r_symndx < symtab_hdr->sh_info)
861         {
862           sym = local_syms + r_symndx;
863           sec = local_sections[r_symndx];
864           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
865         }
866       else
867         {
868           bfd_boolean unresolved_reloc, warned;
869
870           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
871                                    r_symndx, symtab_hdr, sym_hashes,
872                                    h, sec, relocation,
873                                    unresolved_reloc, warned);
874         }
875
876       if (sec != NULL && elf_discarded_section (sec))
877         {
878           /* For relocs against symbols from removed linkonce sections,
879              or sections discarded by a linker script, we just want the
880              section contents zeroed.  Avoid any special processing.  */
881           _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
882           rel->r_info = 0;
883           rel->r_addend = 0;
884           continue;
885         }
886
887       if (info->relocatable)
888         continue;
889
890       r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
891                                         input_section,
892                                         contents, rel->r_offset,
893                                         relocation, rel->r_addend,
894                                         info, sec, h == NULL);
895
896       if (r != bfd_reloc_ok)
897         {
898           const char *name;
899           const char *msg = (const char *) 0;
900
901           if (h != NULL)
902             name = h->root.root.string;
903           else
904             {
905               name = (bfd_elf_string_from_elf_section
906                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
907               if (name == NULL || *name == '\0')
908                 name = bfd_section_name (input_bfd, sec);
909             }
910
911           switch (r)
912             {
913              case bfd_reloc_overflow:
914                if (!((*info->callbacks->reloc_overflow)
915                      (info, (h ? &h->root : NULL), name, howto->name,
916                       (bfd_vma) 0, input_bfd, input_section,
917                       rel->r_offset)))
918                  return FALSE;
919                break;
920
921              case bfd_reloc_undefined:
922                if (!((*info->callbacks->undefined_symbol)
923                      (info, name, input_bfd, input_section,
924                       rel->r_offset, TRUE)))
925                  return FALSE;
926                break;
927
928              case bfd_reloc_outofrange:
929                msg = _("internal error: out of range error");
930                goto common_error;
931
932              case bfd_reloc_notsupported:
933                msg = _("internal error: unsupported relocation error");
934                goto common_error;
935
936              case bfd_reloc_dangerous:
937                msg = _("internal error: dangerous error");
938                goto common_error;
939
940              default:
941                msg = _("internal error: unknown error");
942                /* Fall through.  */
943
944              common_error:
945                if (!((*info->callbacks->warning)
946                      (info, msg, name, input_bfd, input_section,
947                       rel->r_offset)))
948                  return FALSE;
949                break;
950             }
951         }
952     }
953
954   return TRUE;
955 }
956
957 /* This function handles relaxing for the CRX.
958
959    There's quite a few relaxing opportunites available on the CRX:
960
961         * bal/bcond:32 -> bal/bcond:16                             2 bytes
962         * bcond:16 -> bcond:8                                      2 bytes
963         * cmpbcond:24 -> cmpbcond:8                                2 bytes
964         * arithmetic imm32 -> arithmetic imm16                     2 bytes
965
966    Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
967
968 static bfd_boolean
969 elf32_crx_relax_section (bfd *abfd, asection *sec,
970                          struct bfd_link_info *link_info, bfd_boolean *again)
971 {
972   Elf_Internal_Shdr *symtab_hdr;
973   Elf_Internal_Rela *internal_relocs;
974   Elf_Internal_Rela *irel, *irelend;
975   bfd_byte *contents = NULL;
976   Elf_Internal_Sym *isymbuf = NULL;
977
978   /* Assume nothing changes.  */
979   *again = FALSE;
980
981   /* We don't have to do anything for a relocatable link, if
982      this section does not have relocs, or if this is not a
983      code section.  */
984   if (link_info->relocatable
985       || (sec->flags & SEC_RELOC) == 0
986       || sec->reloc_count == 0
987       || (sec->flags & SEC_CODE) == 0)
988     return TRUE;
989
990   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
991
992   /* Get a copy of the native relocations.  */
993   internal_relocs = (_bfd_elf_link_read_relocs
994                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
995                       link_info->keep_memory));
996   if (internal_relocs == NULL)
997     goto error_return;
998
999   /* Walk through them looking for relaxing opportunities.  */
1000   irelend = internal_relocs + sec->reloc_count;
1001   for (irel = internal_relocs; irel < irelend; irel++)
1002     {
1003       bfd_vma symval;
1004
1005       /* If this isn't something that can be relaxed, then ignore
1006          this reloc.  */
1007       if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
1008           && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
1009           && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
1010           && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
1011         continue;
1012
1013       /* Get the section contents if we haven't done so already.  */
1014       if (contents == NULL)
1015         {
1016           /* Get cached copy if it exists.  */
1017           if (elf_section_data (sec)->this_hdr.contents != NULL)
1018             contents = elf_section_data (sec)->this_hdr.contents;
1019           /* Go get them off disk.  */
1020           else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1021             goto error_return;
1022         }
1023
1024       /* Read this BFD's local symbols if we haven't done so already.  */
1025       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1026         {
1027           isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1028           if (isymbuf == NULL)
1029             isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1030                                             symtab_hdr->sh_info, 0,
1031                                             NULL, NULL, NULL);
1032           if (isymbuf == NULL)
1033             goto error_return;
1034         }
1035
1036       /* Get the value of the symbol referred to by the reloc.  */
1037       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1038         {
1039           /* A local symbol.  */
1040           Elf_Internal_Sym *isym;
1041           asection *sym_sec;
1042
1043           isym = isymbuf + ELF32_R_SYM (irel->r_info);
1044           if (isym->st_shndx == SHN_UNDEF)
1045             sym_sec = bfd_und_section_ptr;
1046           else if (isym->st_shndx == SHN_ABS)
1047             sym_sec = bfd_abs_section_ptr;
1048           else if (isym->st_shndx == SHN_COMMON)
1049             sym_sec = bfd_com_section_ptr;
1050           else
1051             sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1052           symval = (isym->st_value
1053                     + sym_sec->output_section->vma
1054                     + sym_sec->output_offset);
1055         }
1056       else
1057         {
1058           unsigned long indx;
1059           struct elf_link_hash_entry *h;
1060
1061           /* An external symbol.  */
1062           indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1063           h = elf_sym_hashes (abfd)[indx];
1064           BFD_ASSERT (h != NULL);
1065
1066           if (h->root.type != bfd_link_hash_defined
1067               && h->root.type != bfd_link_hash_defweak)
1068             /* This appears to be a reference to an undefined
1069                symbol.  Just ignore it--it will be caught by the
1070                regular reloc processing.  */
1071             continue;
1072
1073           symval = (h->root.u.def.value
1074                     + h->root.u.def.section->output_section->vma
1075                     + h->root.u.def.section->output_offset);
1076         }
1077
1078       /* For simplicity of coding, we are going to modify the section
1079          contents, the section relocs, and the BFD symbol table.  We
1080          must tell the rest of the code not to free up this
1081          information.  It would be possible to instead create a table
1082          of changes which have to be made, as is done in coff-mips.c;
1083          that would be more work, but would require less memory when
1084          the linker is run.  */
1085
1086       /* Try to turn a 32bit pc-relative branch/call into
1087          a 16bit pc-relative branch/call.  */
1088       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
1089         {
1090           bfd_vma value = symval;
1091
1092           /* Deal with pc-relative gunk.  */
1093           value -= (sec->output_section->vma + sec->output_offset);
1094           value -= irel->r_offset;
1095           value += irel->r_addend;
1096
1097           /* See if the value will fit in 16 bits, note the high value is
1098              0xfffe + 2 as the target will be two bytes closer if we are
1099              able to relax.  */
1100           if ((long) value < 0x10000 && (long) value > -0x10002)
1101             {
1102               unsigned short code;
1103
1104               /* Get the opcode.  */
1105               code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1106
1107               /* Verify it's a 'bal'/'bcond' and fix the opcode.  */
1108               if ((code & 0xfff0) == 0x3170)
1109                 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1110               else if ((code & 0xf0ff) == 0x707f)
1111                 bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
1112               else
1113                 continue;
1114
1115               /* Note that we've changed the relocs, section contents, etc.  */
1116               elf_section_data (sec)->relocs = internal_relocs;
1117               elf_section_data (sec)->this_hdr.contents = contents;
1118               symtab_hdr->contents = (unsigned char *) isymbuf;
1119
1120               /* Fix the relocation's type.  */
1121               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1122                                            R_CRX_REL16);
1123
1124               /* Delete two bytes of data.  */
1125               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1126                                                    irel->r_offset + 2, 2))
1127                 goto error_return;
1128
1129               /* That will change things, so, we should relax again.
1130                  Note that this is not required, and it may be slow.  */
1131               *again = TRUE;
1132             }
1133         }
1134
1135       /* Try to turn a 16bit pc-relative branch into an
1136          8bit pc-relative branch.  */
1137       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
1138         {
1139           bfd_vma value = symval;
1140
1141           /* Deal with pc-relative gunk.  */
1142           value -= (sec->output_section->vma + sec->output_offset);
1143           value -= irel->r_offset;
1144           value += irel->r_addend;
1145
1146           /* See if the value will fit in 8 bits, note the high value is
1147              0xfc + 2 as the target will be two bytes closer if we are
1148              able to relax.  */
1149           if ((long) value < 0xfe && (long) value > -0x100)
1150             {
1151               unsigned short code;
1152
1153               /* Get the opcode.  */
1154               code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1155
1156               /* Verify it's a 'bcond' opcode.  */
1157               if ((code & 0xf0ff) != 0x707e)
1158                 continue;
1159
1160               /* Note that we've changed the relocs, section contents, etc.  */
1161               elf_section_data (sec)->relocs = internal_relocs;
1162               elf_section_data (sec)->this_hdr.contents = contents;
1163               symtab_hdr->contents = (unsigned char *) isymbuf;
1164
1165               /* Fix the relocation's type.  */
1166               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1167                                            R_CRX_REL8);
1168
1169               /* Delete two bytes of data.  */
1170               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1171                                                    irel->r_offset + 2, 2))
1172                 goto error_return;
1173
1174               /* That will change things, so, we should relax again.
1175                  Note that this is not required, and it may be slow.  */
1176               *again = TRUE;
1177             }
1178         }
1179
1180       /* Try to turn a 24bit pc-relative cmp&branch into
1181          an 8bit pc-relative cmp&branch.  */
1182       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
1183         {
1184           bfd_vma value = symval;
1185
1186           /* Deal with pc-relative gunk.  */
1187           value -= (sec->output_section->vma + sec->output_offset);
1188           value -= irel->r_offset;
1189           value += irel->r_addend;
1190
1191           /* See if the value will fit in 8 bits, note the high value is
1192              0x7e + 2 as the target will be two bytes closer if we are
1193              able to relax.  */
1194           if ((long) value < 0x100 && (long) value > -0x100)
1195             {
1196               unsigned short code;
1197
1198               /* Get the opcode.  */
1199               code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1200
1201               /* Verify it's a 'cmp&branch' opcode.  */
1202               if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
1203                && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
1204                && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
1205                /* Or a Co-processor branch ('bcop').  */
1206                && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
1207                 continue;
1208
1209               /* Note that we've changed the relocs, section contents, etc.  */
1210               elf_section_data (sec)->relocs = internal_relocs;
1211               elf_section_data (sec)->this_hdr.contents = contents;
1212               symtab_hdr->contents = (unsigned char *) isymbuf;
1213
1214               /* Fix the opcode.  */
1215               bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1216
1217               /* Fix the relocation's type.  */
1218               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1219                                            R_CRX_REL8_CMP);
1220
1221               /* Delete two bytes of data.  */
1222               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1223                                                    irel->r_offset + 4, 2))
1224                 goto error_return;
1225
1226               /* That will change things, so, we should relax again.
1227                  Note that this is not required, and it may be slow.  */
1228               *again = TRUE;
1229             }
1230         }
1231
1232       /* Try to turn a 32bit immediate address into
1233          a 16bit immediate address.  */
1234       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
1235         {
1236           bfd_vma value = symval;
1237
1238           /* See if the value will fit in 16 bits.  */
1239           if ((long) value < 0x7fff && (long) value > -0x8000)
1240             {
1241               unsigned short code;
1242
1243               /* Get the opcode.  */
1244               code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1245
1246               /* Verify it's a 'arithmetic double'.  */
1247               if ((code & 0xf0f0) != 0x20f0)
1248                 continue;
1249
1250               /* Note that we've changed the relocs, section contents, etc.  */
1251               elf_section_data (sec)->relocs = internal_relocs;
1252               elf_section_data (sec)->this_hdr.contents = contents;
1253               symtab_hdr->contents = (unsigned char *) isymbuf;
1254
1255               /* Fix the opcode.  */
1256               bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
1257
1258               /* Fix the relocation's type.  */
1259               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1260                                            R_CRX_IMM16);
1261
1262               /* Delete two bytes of data.  */
1263               if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1264                                                    irel->r_offset + 2, 2))
1265                 goto error_return;
1266
1267               /* That will change things, so, we should relax again.
1268                  Note that this is not required, and it may be slow.  */
1269               *again = TRUE;
1270             }
1271         }
1272     }
1273
1274   if (isymbuf != NULL
1275       && symtab_hdr->contents != (unsigned char *) isymbuf)
1276     {
1277       if (! link_info->keep_memory)
1278         free (isymbuf);
1279       else
1280         {
1281           /* Cache the symbols for elf_link_input_bfd.  */
1282           symtab_hdr->contents = (unsigned char *) isymbuf;
1283         }
1284     }
1285
1286   if (contents != NULL
1287       && elf_section_data (sec)->this_hdr.contents != contents)
1288     {
1289       if (! link_info->keep_memory)
1290         free (contents);
1291       else
1292         {
1293           /* Cache the section contents for elf_link_input_bfd.  */
1294           elf_section_data (sec)->this_hdr.contents = contents;
1295         }
1296     }
1297
1298   if (internal_relocs != NULL
1299       && elf_section_data (sec)->relocs != internal_relocs)
1300     free (internal_relocs);
1301
1302   return TRUE;
1303
1304  error_return:
1305   if (isymbuf != NULL
1306       && symtab_hdr->contents != (unsigned char *) isymbuf)
1307     free (isymbuf);
1308   if (contents != NULL
1309       && elf_section_data (sec)->this_hdr.contents != contents)
1310     free (contents);
1311   if (internal_relocs != NULL
1312       && elf_section_data (sec)->relocs != internal_relocs)
1313     free (internal_relocs);
1314
1315   return FALSE;
1316 }
1317
1318 /* Definitions for setting CRX target vector.  */
1319 #define TARGET_LITTLE_SYM               bfd_elf32_crx_vec
1320 #define TARGET_LITTLE_NAME              "elf32-crx"
1321 #define ELF_ARCH                        bfd_arch_crx
1322 #define ELF_MACHINE_CODE                EM_CRX
1323 #define ELF_MAXPAGESIZE                 0x1
1324 #define elf_symbol_leading_char         '_'
1325
1326 #define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup
1327 #define bfd_elf32_bfd_reloc_name_lookup \
1328                                         elf_crx_reloc_name_lookup
1329 #define elf_info_to_howto               elf_crx_info_to_howto
1330 #define elf_info_to_howto_rel           0
1331 #define elf_backend_relocate_section    elf32_crx_relocate_section
1332 #define bfd_elf32_bfd_relax_section     elf32_crx_relax_section
1333 #define bfd_elf32_bfd_get_relocated_section_contents \
1334                                 elf32_crx_get_relocated_section_contents
1335 #define elf_backend_can_gc_sections     1
1336 #define elf_backend_rela_normal         1
1337
1338 #include "elf32-target.h"