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