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