OSDN Git Service

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