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