elf32-crx.c revision 1.1.1.3
1/* BFD back-end for National Semiconductor's CRX ELF
2   Copyright 2004, 2005, 2006, 2007, 2009, 2010, 2012
3   Free Software Foundation, Inc.
4   Written by Tomer Levi, NSC, Israel.
5
6   This file is part of BFD, the Binary File Descriptor library.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21   MA 02110-1301, USA.  */
22
23#include "sysdep.h"
24#include "bfd.h"
25#include "bfdlink.h"
26#include "libbfd.h"
27#include "elf-bfd.h"
28#include "elf/crx.h"
29
30static reloc_howto_type *elf_crx_reloc_type_lookup
31  (bfd *, bfd_reloc_code_real_type);
32static void elf_crx_info_to_howto
33  (bfd *, arelent *, Elf_Internal_Rela *);
34static bfd_boolean elf32_crx_relax_delete_bytes
35  (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
36static bfd_reloc_status_type crx_elf_final_link_relocate
37  (reloc_howto_type *, bfd *, bfd *, asection *,
38   bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
39   struct bfd_link_info *, asection *, int);
40static bfd_boolean elf32_crx_relocate_section
41  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
42   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
43static bfd_boolean elf32_crx_relax_section
44  (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
45static bfd_byte * elf32_crx_get_relocated_section_contents
46  (bfd *, struct bfd_link_info *, struct bfd_link_order *,
47   bfd_byte *, bfd_boolean, asymbol **);
48
49/* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type.  */
50
51struct crx_reloc_map
52{
53  bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum.  */
54  unsigned short crx_reloc_type;	   /* CRX relocation type.  */
55};
56
57static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
58{
59  {BFD_RELOC_NONE,	    R_CRX_NONE},
60  {BFD_RELOC_CRX_REL4,	    R_CRX_REL4},
61  {BFD_RELOC_CRX_REL8,	    R_CRX_REL8},
62  {BFD_RELOC_CRX_REL8_CMP,  R_CRX_REL8_CMP},
63  {BFD_RELOC_CRX_REL16,	    R_CRX_REL16},
64  {BFD_RELOC_CRX_REL24,	    R_CRX_REL24},
65  {BFD_RELOC_CRX_REL32,	    R_CRX_REL32},
66  {BFD_RELOC_CRX_REGREL12,  R_CRX_REGREL12},
67  {BFD_RELOC_CRX_REGREL22,  R_CRX_REGREL22},
68  {BFD_RELOC_CRX_REGREL28,  R_CRX_REGREL28},
69  {BFD_RELOC_CRX_REGREL32,  R_CRX_REGREL32},
70  {BFD_RELOC_CRX_ABS16,	    R_CRX_ABS16},
71  {BFD_RELOC_CRX_ABS32,	    R_CRX_ABS32},
72  {BFD_RELOC_CRX_NUM8,	    R_CRX_NUM8},
73  {BFD_RELOC_CRX_NUM16,	    R_CRX_NUM16},
74  {BFD_RELOC_CRX_NUM32,	    R_CRX_NUM32},
75  {BFD_RELOC_CRX_IMM16,	    R_CRX_IMM16},
76  {BFD_RELOC_CRX_IMM32,	    R_CRX_IMM32},
77  {BFD_RELOC_CRX_SWITCH8,   R_CRX_SWITCH8},
78  {BFD_RELOC_CRX_SWITCH16,  R_CRX_SWITCH16},
79  {BFD_RELOC_CRX_SWITCH32,  R_CRX_SWITCH32}
80};
81
82static reloc_howto_type crx_elf_howto_table[] =
83{
84  HOWTO (R_CRX_NONE,		/* type */
85	 0,			/* rightshift */
86	 2,			/* size */
87	 32,			/* bitsize */
88	 FALSE,			/* pc_relative */
89	 0,			/* bitpos */
90	 complain_overflow_dont,/* complain_on_overflow */
91	 bfd_elf_generic_reloc,	/* special_function */
92	 "R_CRX_NONE",		/* name */
93	 FALSE,			/* partial_inplace */
94	 0,			/* src_mask */
95	 0,			/* dst_mask */
96	 FALSE),		/* pcrel_offset */
97
98  HOWTO (R_CRX_REL4,		/* type */
99	 1,			/* rightshift */
100	 0,			/* size */
101	 4,			/* bitsize */
102	 TRUE,			/* pc_relative */
103	 0,			/* bitpos */
104	 complain_overflow_bitfield,/* complain_on_overflow */
105	 bfd_elf_generic_reloc,	/* special_function */
106	 "R_CRX_REL4",		/* name */
107	 FALSE,			/* partial_inplace */
108	 0x0,			/* src_mask */
109	 0xf,			/* dst_mask */
110	 FALSE),		/* pcrel_offset */
111
112  HOWTO (R_CRX_REL8,		/* type */
113	 1,			/* rightshift */
114	 0,			/* size */
115	 8,			/* bitsize */
116	 TRUE,			/* pc_relative */
117	 0,			/* bitpos */
118	 complain_overflow_bitfield,/* complain_on_overflow */
119	 bfd_elf_generic_reloc,	/* special_function */
120	 "R_CRX_REL8",		/* name */
121	 FALSE,			/* partial_inplace */
122	 0x0,			/* src_mask */
123	 0xff,			/* dst_mask */
124	 FALSE),		/* pcrel_offset */
125
126  HOWTO (R_CRX_REL8_CMP,	/* type */
127	 1,			/* rightshift */
128	 0,			/* size */
129	 8,			/* bitsize */
130	 TRUE,			/* pc_relative */
131	 0,			/* bitpos */
132	 complain_overflow_bitfield,/* complain_on_overflow */
133	 bfd_elf_generic_reloc,	/* special_function */
134	 "R_CRX_REL8_CMP",	/* name */
135	 FALSE,			/* partial_inplace */
136	 0x0,			/* src_mask */
137	 0xff,			/* dst_mask */
138	 FALSE),		/* pcrel_offset */
139
140  HOWTO (R_CRX_REL16,		/* type */
141	 1,			/* rightshift */
142	 1,			/* size */
143	 16,			/* bitsize */
144	 TRUE,			/* pc_relative */
145	 0,			/* bitpos */
146	 complain_overflow_bitfield,/* complain_on_overflow */
147	 bfd_elf_generic_reloc,	/* special_function */
148	 "R_CRX_REL16",		/* name */
149	 FALSE,			/* partial_inplace */
150	 0x0,			/* src_mask */
151	 0xffff,		/* dst_mask */
152	 FALSE),		/* pcrel_offset */
153
154  HOWTO (R_CRX_REL24,		/* type */
155	 1,			/* rightshift */
156	 2,			/* size */
157	 24,			/* bitsize */
158	 TRUE,			/* pc_relative */
159	 0,			/* bitpos */
160	 complain_overflow_bitfield,/* complain_on_overflow */
161	 bfd_elf_generic_reloc,	/* special_function */
162	 "R_CRX_REL24",		/* name */
163	 FALSE,			/* partial_inplace */
164	 0x0,			/* src_mask */
165	 0xffffff,		/* dst_mask */
166	 FALSE),		/* pcrel_offset */
167
168  HOWTO (R_CRX_REL32,		/* type */
169	 1,			/* rightshift */
170	 2,			/* size */
171	 32,			/* bitsize */
172	 TRUE,			/* pc_relative */
173	 0,			/* bitpos */
174	 complain_overflow_bitfield,/* complain_on_overflow */
175	 bfd_elf_generic_reloc,	/* special_function */
176	 "R_CRX_REL32",		/* name */
177	 FALSE,			/* partial_inplace */
178	 0x0,			/* src_mask */
179	 0xffffffff,		/* dst_mask */
180	 FALSE),		/* pcrel_offset */
181
182  HOWTO (R_CRX_REGREL12,	/* type */
183	 0,			/* rightshift */
184	 1,			/* size */
185	 12,			/* bitsize */
186	 FALSE,			/* pc_relative */
187	 0,			/* bitpos */
188	 complain_overflow_bitfield,/* complain_on_overflow */
189	 bfd_elf_generic_reloc,	/* special_function */
190	 "R_CRX_REGREL12",	/* name */
191	 FALSE,			/* partial_inplace */
192	 0x0,			/* src_mask */
193	 0xfff,			/* dst_mask */
194	 FALSE),		/* pcrel_offset */
195
196  HOWTO (R_CRX_REGREL22,	/* type */
197	 0,			/* rightshift */
198	 2,			/* size */
199	 22,			/* bitsize */
200	 FALSE,			/* pc_relative */
201	 0,			/* bitpos */
202	 complain_overflow_bitfield,/* complain_on_overflow */
203	 bfd_elf_generic_reloc,	/* special_function */
204	 "R_CRX_REGREL22",	/* name */
205	 FALSE,			/* partial_inplace */
206	 0x0,			/* src_mask */
207	 0x3fffff,		/* dst_mask */
208	 FALSE),		/* pcrel_offset */
209
210  HOWTO (R_CRX_REGREL28,	/* type */
211	 0,			/* rightshift */
212	 2,			/* size */
213	 28,			/* bitsize */
214	 FALSE,			/* pc_relative */
215	 0,			/* bitpos */
216	 complain_overflow_bitfield,/* complain_on_overflow */
217	 bfd_elf_generic_reloc,	/* special_function */
218	 "R_CRX_REGREL28",	/* name */
219	 FALSE,			/* partial_inplace */
220	 0x0,			/* src_mask */
221	 0xfffffff,		/* dst_mask */
222	 FALSE),		/* pcrel_offset */
223
224  HOWTO (R_CRX_REGREL32,	/* type */
225	 0,			/* rightshift */
226	 2,			/* size */
227	 32,			/* bitsize */
228	 FALSE,			/* pc_relative */
229	 0,			/* bitpos */
230	 complain_overflow_bitfield,/* complain_on_overflow */
231	 bfd_elf_generic_reloc,	/* special_function */
232	 "R_CRX_REGREL32",	/* name */
233	 FALSE,			/* partial_inplace */
234	 0x0,			/* src_mask */
235	 0xffffffff,		/* dst_mask */
236	 FALSE),		/* pcrel_offset */
237
238  HOWTO (R_CRX_ABS16,		/* type */
239	 0,			/* rightshift */
240	 1,			/* size */
241	 16,			/* bitsize */
242	 FALSE,			/* pc_relative */
243	 0,			/* bitpos */
244	 complain_overflow_bitfield,/* complain_on_overflow */
245	 bfd_elf_generic_reloc,	/* special_function */
246	 "R_CRX_ABS16",		/* name */
247	 FALSE,			/* partial_inplace */
248	 0x0,			/* src_mask */
249	 0xffff,		/* dst_mask */
250	 FALSE),		/* pcrel_offset */
251
252  HOWTO (R_CRX_ABS32,		/* type */
253	 0,			/* rightshift */
254	 2,			/* size */
255	 32,			/* bitsize */
256	 FALSE,			/* pc_relative */
257	 0,			/* bitpos */
258	 complain_overflow_bitfield,/* complain_on_overflow */
259	 bfd_elf_generic_reloc,	/* special_function */
260	 "R_CRX_ABS32",		/* name */
261	 FALSE,			/* partial_inplace */
262	 0x0,			/* src_mask */
263	 0xffffffff,		/* dst_mask */
264	 FALSE),		/* pcrel_offset */
265
266  HOWTO (R_CRX_NUM8,		/* type */
267	 0,			/* rightshift */
268	 0,			/* size */
269	 8,			/* bitsize */
270	 FALSE,			/* pc_relative */
271	 0,			/* bitpos */
272	 complain_overflow_bitfield,/* complain_on_overflow */
273	 bfd_elf_generic_reloc,	/* special_function */
274	 "R_CRX_NUM8",		/* name */
275	 FALSE,			/* partial_inplace */
276	 0x0,	  		/* src_mask */
277	 0xff,			/* dst_mask */
278	 FALSE),		/* pcrel_offset */
279
280  HOWTO (R_CRX_NUM16,		/* type */
281	 0,			/* rightshift */
282	 1,			/* size */
283	 16,			/* bitsize */
284	 FALSE,			/* pc_relative */
285	 0,			/* bitpos */
286	 complain_overflow_bitfield,/* complain_on_overflow */
287	 bfd_elf_generic_reloc,	/* special_function */
288	 "R_CRX_NUM16",		/* name */
289	 FALSE,			/* partial_inplace */
290	 0x0,	  		/* src_mask */
291	 0xffff,		/* dst_mask */
292	 FALSE),		/* pcrel_offset */
293
294  HOWTO (R_CRX_NUM32,		/* type */
295	 0,			/* rightshift */
296	 2,			/* size */
297	 32,			/* bitsize */
298	 FALSE,			/* pc_relative */
299	 0,			/* bitpos */
300	 complain_overflow_bitfield,/* complain_on_overflow */
301	 bfd_elf_generic_reloc,	/* special_function */
302	 "R_CRX_NUM32",		/* name */
303	 FALSE,			/* partial_inplace */
304	 0x0,	  		/* src_mask */
305	 0xffffffff,		/* dst_mask */
306	 FALSE),		/* pcrel_offset */
307
308  HOWTO (R_CRX_IMM16,		/* type */
309	 0,			/* rightshift */
310	 1,			/* size */
311	 16,			/* bitsize */
312	 FALSE,			/* pc_relative */
313	 0,			/* bitpos */
314	 complain_overflow_bitfield,/* complain_on_overflow */
315	 bfd_elf_generic_reloc,	/* special_function */
316	 "R_CRX_IMM16",		/* name */
317	 FALSE,			/* partial_inplace */
318	 0x0, 	 		/* src_mask */
319	 0xffff,		/* dst_mask */
320	 FALSE),		/* pcrel_offset */
321
322  HOWTO (R_CRX_IMM32,		/* type */
323	 0,			/* rightshift */
324	 2,			/* size */
325	 32,			/* bitsize */
326	 FALSE,			/* pc_relative */
327	 0,			/* bitpos */
328	 complain_overflow_bitfield,/* complain_on_overflow */
329	 bfd_elf_generic_reloc,	/* special_function */
330	 "R_CRX_IMM32",		/* name */
331	 FALSE,			/* partial_inplace */
332	 0x0,  			/* src_mask */
333	 0xffffffff,		/* dst_mask */
334	 FALSE),		/* pcrel_offset */
335
336  /* An 8 bit switch table entry.  This is generated for an expression
337     such as ``.byte L1 - L2''.  The offset holds the difference
338     between the reloc address and L2.  */
339  HOWTO (R_CRX_SWITCH8,		/* type */
340	 0,			/* rightshift */
341	 0,			/* size (0 = byte, 1 = short, 2 = long) */
342	 8,			/* bitsize */
343	 FALSE,			/* pc_relative */
344	 0,			/* bitpos */
345	 complain_overflow_unsigned, /* complain_on_overflow */
346	 bfd_elf_generic_reloc,	/* special_function */
347	 "R_CRX_SWITCH8",	/* name */
348	 FALSE,			/* partial_inplace */
349	 0x0,			/* src_mask */
350	 0xff,			/* dst_mask */
351	 TRUE),			/* pcrel_offset */
352
353  /* A 16 bit switch table entry.  This is generated for an expression
354     such as ``.word L1 - L2''.  The offset holds the difference
355     between the reloc address and L2.  */
356  HOWTO (R_CRX_SWITCH16,	/* type */
357	 0,			/* rightshift */
358	 1,			/* size (0 = byte, 1 = short, 2 = long) */
359	 16,			/* bitsize */
360	 FALSE,			/* pc_relative */
361	 0,			/* bitpos */
362	 complain_overflow_unsigned, /* complain_on_overflow */
363	 bfd_elf_generic_reloc,	/* special_function */
364	 "R_CRX_SWITCH16",	/* name */
365	 FALSE,			/* partial_inplace */
366	 0x0,			/* src_mask */
367	 0xffff,		/* dst_mask */
368	 TRUE),			/* pcrel_offset */
369
370  /* A 32 bit switch table entry.  This is generated for an expression
371     such as ``.long L1 - L2''.  The offset holds the difference
372     between the reloc address and L2.  */
373  HOWTO (R_CRX_SWITCH32,	/* type */
374	 0,			/* rightshift */
375	 2,			/* size (0 = byte, 1 = short, 2 = long) */
376	 32,			/* bitsize */
377	 FALSE,			/* pc_relative */
378	 0,			/* bitpos */
379	 complain_overflow_unsigned, /* complain_on_overflow */
380	 bfd_elf_generic_reloc,	/* special_function */
381	 "R_CRX_SWITCH32",	/* name */
382	 FALSE,			/* partial_inplace */
383	 0x0,			/* src_mask */
384	 0xffffffff,		/* dst_mask */
385	 TRUE)			/* pcrel_offset */
386};
387
388/* Retrieve a howto ptr using a BFD reloc_code.  */
389
390static reloc_howto_type *
391elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
392			   bfd_reloc_code_real_type code)
393{
394  unsigned int i;
395
396  for (i = 0; i < R_CRX_MAX; i++)
397    if (code == crx_reloc_map[i].bfd_reloc_enum)
398      return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
399
400  printf ("This relocation Type is not supported -0x%x\n", code);
401  return 0;
402}
403
404static reloc_howto_type *
405elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
406			   const char *r_name)
407{
408  unsigned int i;
409
410  for (i = 0;
411       i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]);
412       i++)
413    if (crx_elf_howto_table[i].name != NULL
414	&& strcasecmp (crx_elf_howto_table[i].name, r_name) == 0)
415      return &crx_elf_howto_table[i];
416
417  return NULL;
418}
419
420/* Retrieve a howto ptr using an internal relocation entry.  */
421
422static void
423elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
424		       Elf_Internal_Rela *dst)
425{
426  unsigned int r_type = ELF32_R_TYPE (dst->r_info);
427  BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
428  cache_ptr->howto = &crx_elf_howto_table[r_type];
429}
430
431/* Perform a relocation as part of a final link.  */
432
433static bfd_reloc_status_type
434crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
435			     bfd *output_bfd ATTRIBUTE_UNUSED,
436			     asection *input_section, bfd_byte *contents,
437			     bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
438			     struct bfd_link_info *info ATTRIBUTE_UNUSED,
439			     asection *sec ATTRIBUTE_UNUSED,
440			     int is_local ATTRIBUTE_UNUSED)
441{
442  unsigned short r_type = howto->type;
443  bfd_byte *hit_data = contents + offset;
444  bfd_vma reloc_bits, check;
445
446  switch (r_type)
447    {
448     case R_CRX_IMM16:
449     case R_CRX_IMM32:
450     case R_CRX_ABS16:
451     case R_CRX_ABS32:
452     case R_CRX_REL8_CMP:
453     case R_CRX_REL16:
454     case R_CRX_REL24:
455     case R_CRX_REL32:
456     case R_CRX_REGREL12:
457     case R_CRX_REGREL22:
458     case R_CRX_REGREL28:
459     case R_CRX_REGREL32:
460       /* 'hit_data' is relative to the start of the instruction, not the
461	  relocation offset. Advance it to account for the exact offset.  */
462       hit_data += 2;
463       break;
464
465     case R_CRX_REL4:
466       /* This relocation type is used only in 'Branch if Equal to 0'
467	  instructions and requires special handling.  */
468       Rvalue -= 1;
469       break;
470
471     case R_CRX_NONE:
472       return bfd_reloc_ok;
473       break;
474
475     case R_CRX_SWITCH8:
476     case R_CRX_SWITCH16:
477     case R_CRX_SWITCH32:
478       /* We only care about the addend, where the difference between
479	  expressions is kept.  */
480       Rvalue = 0;
481
482     default:
483       break;
484    }
485
486  if (howto->pc_relative)
487    {
488      /* Subtract the address of the section containing the location.  */
489      Rvalue -= (input_section->output_section->vma
490		 + input_section->output_offset);
491      /* Subtract the position of the location within the section.  */
492      Rvalue -= offset;
493    }
494
495  /* Add in supplied addend.  */
496  Rvalue += addend;
497
498  /* Complain if the bitfield overflows, whether it is considered
499     as signed or unsigned.  */
500  check = Rvalue >> howto->rightshift;
501
502  /* Assumes two's complement.  This expression avoids
503     overflow if howto->bitsize is the number of bits in
504     bfd_vma.  */
505  reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
506
507  if (((bfd_vma) check & ~reloc_bits) != 0
508      && (((bfd_vma) check & ~reloc_bits)
509	  != (-(bfd_vma) 1 & ~reloc_bits)))
510    {
511      /* The above right shift is incorrect for a signed
512	 value.  See if turning on the upper bits fixes the
513	 overflow.  */
514      if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
515	{
516	  check |= ((bfd_vma) - 1
517		    & ~((bfd_vma) - 1
518			>> howto->rightshift));
519	  if (((bfd_vma) check & ~reloc_bits)
520	      != (-(bfd_vma) 1 & ~reloc_bits))
521	    return bfd_reloc_overflow;
522	}
523      else
524	return bfd_reloc_overflow;
525    }
526
527  /* Drop unwanted bits from the value we are relocating to.  */
528  Rvalue >>= (bfd_vma) howto->rightshift;
529
530  /* Apply dst_mask to select only relocatable part of the insn.  */
531  Rvalue &= howto->dst_mask;
532
533  switch (howto->size)
534    {
535     case 0:
536       if (r_type == R_CRX_REL4)
537	 {
538	   Rvalue <<= 4;
539	   Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
540	 }
541
542       bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
543       break;
544
545     case 1:
546       if (r_type == R_CRX_REGREL12)
547	 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
548
549       bfd_put_16 (input_bfd, Rvalue, hit_data);
550       break;
551
552     case 2:
553       if (r_type == R_CRX_REL24
554	   || r_type == R_CRX_REGREL22
555	   || r_type == R_CRX_REGREL28)
556	 Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
557		      bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
558
559       if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
560	 /* Relocation on DATA is purely little-endian, that is, for a
561	    multi-byte datum, the lowest address in memory contains the
562	    little end of the datum, that is, the least significant byte.
563	    Therefore we use BFD's byte Putting functions.  */
564	 bfd_put_32 (input_bfd, Rvalue, hit_data);
565       else
566	 /* Relocation on INSTRUCTIONS is different : Instructions are
567	    word-addressable, that is, each word itself is arranged according
568	    to little-endian convention, whereas the words are arranged with
569	    respect to one another in BIG ENDIAN fashion.
570	    When there is an immediate value that spans a word boundary, it is
571	    split in a big-endian way with respect to the words.  */
572	 {
573	   bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
574	   bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
575	 }
576     break;
577
578     default:
579       return bfd_reloc_notsupported;
580    }
581
582  return bfd_reloc_ok;
583}
584
585/* Delete some bytes from a section while relaxing.  */
586
587static bfd_boolean
588elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
589			      asection *sec, bfd_vma addr, int count)
590{
591  Elf_Internal_Shdr *symtab_hdr;
592  unsigned int sec_shndx;
593  bfd_byte *contents;
594  Elf_Internal_Rela *irel, *irelend;
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  toaddr = sec->size;
608
609  irel = elf_section_data (sec)->relocs;
610  irelend = irel + sec->reloc_count;
611
612  /* Actually delete the bytes.  */
613  memmove (contents + addr, contents + addr + count,
614	   (size_t) (toaddr - addr - count));
615  sec->size -= count;
616
617  /* Adjust all the relocs.  */
618  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
619    {
620      /* Get the new reloc address.  */
621      if ((irel->r_offset > addr
622	   && irel->r_offset < toaddr))
623	irel->r_offset -= count;
624    }
625
626  /* Adjust the local symbols defined in this section.  */
627  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
628  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
629  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
630    {
631      if (isym->st_shndx == sec_shndx
632	  && isym->st_value > addr
633	  && isym->st_value < toaddr)
634	{
635	  /* Adjust the addend of SWITCH relocations in this section,
636	     which reference this local symbol.  */
637	  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
638	    {
639	      unsigned long r_symndx;
640	      Elf_Internal_Sym *rsym;
641	      bfd_vma addsym, subsym;
642
643	      /* Skip if not a SWITCH relocation.  */
644	      if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
645		  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
646		  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
647		  continue;
648
649	      r_symndx = ELF32_R_SYM (irel->r_info);
650	      rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
651
652	      /* Skip if not the local adjusted symbol.  */
653	      if (rsym != isym)
654		continue;
655
656	      addsym = isym->st_value;
657	      subsym = addsym - irel->r_addend;
658
659	      /* Fix the addend only when -->> (addsym > addr >= subsym).  */
660	      if (subsym <= addr)
661		irel->r_addend -= count;
662	      else
663		continue;
664	    }
665
666	  isym->st_value -= count;
667	}
668    }
669
670  /* Now adjust the global symbols defined in this section.  */
671  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
672	      - symtab_hdr->sh_info);
673  sym_hashes = start_hashes = elf_sym_hashes (abfd);
674  end_hashes = sym_hashes + symcount;
675
676  for (; sym_hashes < end_hashes; sym_hashes++)
677    {
678      struct elf_link_hash_entry *sym_hash = *sym_hashes;
679
680      /* The '--wrap SYMBOL' option is causing a pain when the object file,
681	 containing the definition of __wrap_SYMBOL, includes a direct
682	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
683	 the same symbol (which is __wrap_SYMBOL), but still exist as two
684	 different symbols in 'sym_hashes', we don't want to adjust
685	 the global symbol __wrap_SYMBOL twice.
686	 This check is only relevant when symbols are being wrapped.  */
687      if (link_info->wrap_hash != NULL)
688	{
689	  struct elf_link_hash_entry **cur_sym_hashes;
690
691	  /* Loop only over the symbols whom been already checked.  */
692	  for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
693	       cur_sym_hashes++)
694	    {
695	      /* If the current symbol is identical to 'sym_hash', that means
696		 the symbol was already adjusted (or at least checked).  */
697	      if (*cur_sym_hashes == sym_hash)
698		break;
699	    }
700	  /* Don't adjust the symbol again.  */
701	  if (cur_sym_hashes < sym_hashes)
702	    continue;
703	}
704
705      if ((sym_hash->root.type == bfd_link_hash_defined
706	   || sym_hash->root.type == bfd_link_hash_defweak)
707	  && sym_hash->root.u.def.section == sec
708	  && sym_hash->root.u.def.value > addr
709	  && sym_hash->root.u.def.value < toaddr)
710	sym_hash->root.u.def.value -= count;
711    }
712
713  return TRUE;
714}
715
716/* This is a version of bfd_generic_get_relocated_section_contents
717   which uses elf32_crx_relocate_section.  */
718
719static bfd_byte *
720elf32_crx_get_relocated_section_contents (bfd *output_bfd,
721					  struct bfd_link_info *link_info,
722					  struct bfd_link_order *link_order,
723					  bfd_byte *data,
724					  bfd_boolean relocatable,
725					  asymbol **symbols)
726{
727  Elf_Internal_Shdr *symtab_hdr;
728  asection *input_section = link_order->u.indirect.section;
729  bfd *input_bfd = input_section->owner;
730  asection **sections = NULL;
731  Elf_Internal_Rela *internal_relocs = NULL;
732  Elf_Internal_Sym *isymbuf = NULL;
733
734  /* We only need to handle the case of relaxing, or of having a
735     particular set of section contents, specially.  */
736  if (relocatable
737      || elf_section_data (input_section)->this_hdr.contents == NULL)
738    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
739						       link_order, data,
740						       relocatable,
741						       symbols);
742
743  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
744
745  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
746	  (size_t) input_section->size);
747
748  if ((input_section->flags & SEC_RELOC) != 0
749      && input_section->reloc_count > 0)
750    {
751      Elf_Internal_Sym *isym;
752      Elf_Internal_Sym *isymend;
753      asection **secpp;
754      bfd_size_type amt;
755
756      internal_relocs = (_bfd_elf_link_read_relocs
757			 (input_bfd, input_section, NULL,
758			  (Elf_Internal_Rela *) NULL, FALSE));
759      if (internal_relocs == NULL)
760	goto error_return;
761
762      if (symtab_hdr->sh_info != 0)
763	{
764	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
765	  if (isymbuf == NULL)
766	    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
767					    symtab_hdr->sh_info, 0,
768					    NULL, NULL, NULL);
769	  if (isymbuf == NULL)
770	    goto error_return;
771	}
772
773      amt = symtab_hdr->sh_info;
774      amt *= sizeof (asection *);
775      sections = bfd_malloc (amt);
776      if (sections == NULL && amt != 0)
777	goto error_return;
778
779      isymend = isymbuf + symtab_hdr->sh_info;
780      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
781	{
782	  asection *isec;
783
784	  if (isym->st_shndx == SHN_UNDEF)
785	    isec = bfd_und_section_ptr;
786	  else if (isym->st_shndx == SHN_ABS)
787	    isec = bfd_abs_section_ptr;
788	  else if (isym->st_shndx == SHN_COMMON)
789	    isec = bfd_com_section_ptr;
790	  else
791	    isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
792
793	  *secpp = isec;
794	}
795
796      if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
797				     input_section, data, internal_relocs,
798				     isymbuf, sections))
799	goto error_return;
800
801      if (sections != NULL)
802	free (sections);
803      if (isymbuf != NULL
804	  && symtab_hdr->contents != (unsigned char *) isymbuf)
805	free (isymbuf);
806      if (elf_section_data (input_section)->relocs != internal_relocs)
807	free (internal_relocs);
808    }
809
810  return data;
811
812 error_return:
813  if (sections != NULL)
814    free (sections);
815  if (isymbuf != NULL
816      && symtab_hdr->contents != (unsigned char *) isymbuf)
817    free (isymbuf);
818  if (internal_relocs != NULL
819      && elf_section_data (input_section)->relocs != internal_relocs)
820    free (internal_relocs);
821  return NULL;
822}
823
824/* Relocate a CRX ELF section.  */
825
826static bfd_boolean
827elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
828			    bfd *input_bfd, asection *input_section,
829			    bfd_byte *contents, Elf_Internal_Rela *relocs,
830			    Elf_Internal_Sym *local_syms,
831			    asection **local_sections)
832{
833  Elf_Internal_Shdr *symtab_hdr;
834  struct elf_link_hash_entry **sym_hashes;
835  Elf_Internal_Rela *rel, *relend;
836
837  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
838  sym_hashes = elf_sym_hashes (input_bfd);
839
840  rel = relocs;
841  relend = relocs + input_section->reloc_count;
842  for (; rel < relend; rel++)
843    {
844      int r_type;
845      reloc_howto_type *howto;
846      unsigned long r_symndx;
847      Elf_Internal_Sym *sym;
848      asection *sec;
849      struct elf_link_hash_entry *h;
850      bfd_vma relocation;
851      bfd_reloc_status_type r;
852
853      r_symndx = ELF32_R_SYM (rel->r_info);
854      r_type = ELF32_R_TYPE (rel->r_info);
855      howto = crx_elf_howto_table + (r_type);
856
857      h = NULL;
858      sym = NULL;
859      sec = NULL;
860      if (r_symndx < symtab_hdr->sh_info)
861	{
862	  sym = local_syms + r_symndx;
863	  sec = local_sections[r_symndx];
864	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
865	}
866      else
867	{
868	  bfd_boolean unresolved_reloc, warned;
869
870	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
871				   r_symndx, symtab_hdr, sym_hashes,
872				   h, sec, relocation,
873				   unresolved_reloc, warned);
874	}
875
876      if (sec != NULL && discarded_section (sec))
877	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
878					 rel, 1, relend, howto, 0, contents);
879
880      if (info->relocatable)
881	continue;
882
883      r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
884					input_section,
885					contents, rel->r_offset,
886					relocation, rel->r_addend,
887					info, sec, h == NULL);
888
889      if (r != bfd_reloc_ok)
890	{
891	  const char *name;
892	  const char *msg = (const char *) 0;
893
894	  if (h != NULL)
895	    name = h->root.root.string;
896	  else
897	    {
898	      name = (bfd_elf_string_from_elf_section
899		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
900	      if (name == NULL || *name == '\0')
901		name = bfd_section_name (input_bfd, sec);
902	    }
903
904	  switch (r)
905	    {
906	     case bfd_reloc_overflow:
907	       if (!((*info->callbacks->reloc_overflow)
908		     (info, (h ? &h->root : NULL), name, howto->name,
909		      (bfd_vma) 0, input_bfd, input_section,
910		      rel->r_offset)))
911		 return FALSE;
912	       break;
913
914	     case bfd_reloc_undefined:
915	       if (!((*info->callbacks->undefined_symbol)
916		     (info, name, input_bfd, input_section,
917		      rel->r_offset, TRUE)))
918		 return FALSE;
919	       break;
920
921	     case bfd_reloc_outofrange:
922	       msg = _("internal error: out of range error");
923	       goto common_error;
924
925	     case bfd_reloc_notsupported:
926	       msg = _("internal error: unsupported relocation error");
927	       goto common_error;
928
929	     case bfd_reloc_dangerous:
930	       msg = _("internal error: dangerous error");
931	       goto common_error;
932
933	     default:
934	       msg = _("internal error: unknown error");
935	       /* Fall through.  */
936
937	     common_error:
938	       if (!((*info->callbacks->warning)
939		     (info, msg, name, input_bfd, input_section,
940		      rel->r_offset)))
941		 return FALSE;
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 (link_info->relocatable
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		bfd_elf32_crx_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