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