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