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