1/* BFD back-end for National Semiconductor's CRX ELF
2   Copyright 2004, 2005, 2006, 2007 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
29static reloc_howto_type *elf_crx_reloc_type_lookup
30  (bfd *, bfd_reloc_code_real_type);
31static void elf_crx_info_to_howto
32  (bfd *, arelent *, Elf_Internal_Rela *);
33static bfd_boolean elf32_crx_relax_delete_bytes
34  (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
35static 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);
39static bfd_boolean elf32_crx_relocate_section
40  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
41   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
42static bfd_boolean elf32_crx_relax_section
43  (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
44static 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
50struct 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
56static 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
81static 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	 0xf,			/* 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	 0xff,			/* 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	 0xff,			/* 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	 0xffff,		/* 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	 0xffffff,		/* 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	 0xffffffff,		/* 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	 0xfff,			/* 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	 0x3fffff,		/* 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	 0xfffffff,		/* 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	 0xffffffff,		/* 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	 0xffff,		/* 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	 0xffffffff,		/* 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	 0xff,	  		/* 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	 0xffff,  		/* 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	 0xffffffff,  		/* 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	 0xffff,  		/* 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	 0xffffffff,  		/* 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	 0xff,			/* 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	 0xffff,		/* 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	 0xffffffff,		/* src_mask */
383	 0xffffffff,		/* dst_mask */
384	 TRUE)			/* pcrel_offset */
385};
386
387/* Retrieve a howto ptr using a BFD reloc_code.  */
388
389static reloc_howto_type *
390elf_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
403static reloc_howto_type *
404elf_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
421static void
422elf_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
432static bfd_reloc_status_type
433crx_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
586static bfd_boolean
587elf32_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
723static bfd_byte *
724elf32_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
830static bfd_boolean
831elf32_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
972static bfd_boolean
973elf32_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"
1343