xref: /netbsd-src/external/gpl3/gdb/dist/bfd/elf32-crx.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
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 
30 static reloc_howto_type *elf_crx_reloc_type_lookup
31   (bfd *, bfd_reloc_code_real_type);
32 static void elf_crx_info_to_howto
33   (bfd *, arelent *, Elf_Internal_Rela *);
34 static bfd_boolean elf32_crx_relax_delete_bytes
35   (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
36 static 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);
40 static bfd_boolean elf32_crx_relocate_section
41   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
42    Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
43 static bfd_boolean elf32_crx_relax_section
44   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
45 static 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 
51 struct 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 
57 static 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 
82 static 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 
390 static reloc_howto_type *
391 elf_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 
404 static reloc_howto_type *
405 elf_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 
422 static void
423 elf_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 
433 static bfd_reloc_status_type
434 crx_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 
587 static bfd_boolean
588 elf32_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 
719 static bfd_byte *
720 elf32_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 
826 static bfd_boolean
827 elf32_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, ignored;
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, ignored);
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 
961 static bfd_boolean
962 elf32_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