xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/elf32-crx.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* BFD back-end for National Semiconductor's CRX ELF
2    Copyright (C) 2004-2022 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 bool elf_crx_info_to_howto
32   (bfd *, arelent *, Elf_Internal_Rela *);
33 static bool 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 int elf32_crx_relocate_section
40   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
41    Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
42 static bool elf32_crx_relax_section
43   (bfd *, asection *, struct bfd_link_info *, bool *);
44 static bfd_byte * elf32_crx_get_relocated_section_contents
45   (bfd *, struct bfd_link_info *, struct bfd_link_order *,
46    bfd_byte *, bool, 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 	 0,			/* size */
86 	 0,			/* bitsize */
87 	 false,			/* pc_relative */
88 	 0,			/* bitpos */
89 	 complain_overflow_dont,/* complain_on_overflow */
90 	 bfd_elf_generic_reloc,	/* special_function */
91 	 "R_CRX_NONE",		/* name */
92 	 false,			/* partial_inplace */
93 	 0,			/* src_mask */
94 	 0,			/* dst_mask */
95 	 false),		/* pcrel_offset */
96 
97   HOWTO (R_CRX_REL4,		/* type */
98 	 1,			/* rightshift */
99 	 1,			/* 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 	 1,			/* 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 	 1,			/* 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 	 2,			/* 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 	 4,			/* 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 	 4,			/* 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 	 2,			/* 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 	 4,			/* 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 	 4,			/* 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 	 4,			/* 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 	 2,			/* 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 	 4,			/* 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 	 1,			/* 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 	 2,			/* 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 	 4,			/* 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 	 2,			/* 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 	 4,			/* 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 	 1,			/* size */
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 	 2,			/* size */
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 	 4,			/* size */
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 bool
elf_crx_info_to_howto(bfd * abfd,arelent * cache_ptr,Elf_Internal_Rela * dst)422 elf_crx_info_to_howto (bfd *abfd, arelent *cache_ptr,
423 		       Elf_Internal_Rela *dst)
424 {
425   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
426   if (r_type >= R_CRX_MAX)
427     {
428       /* xgettext:c-format */
429       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
430 			  abfd, r_type);
431       bfd_set_error (bfd_error_bad_value);
432       return false;
433     }
434   cache_ptr->howto = &crx_elf_howto_table[r_type];
435   return true;
436 }
437 
438 /* Perform a relocation as part of a final link.  */
439 
440 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)441 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
442 			     bfd *output_bfd ATTRIBUTE_UNUSED,
443 			     asection *input_section, bfd_byte *contents,
444 			     bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
445 			     struct bfd_link_info *info ATTRIBUTE_UNUSED,
446 			     asection *sec ATTRIBUTE_UNUSED,
447 			     int is_local ATTRIBUTE_UNUSED)
448 {
449   unsigned short r_type = howto->type;
450   bfd_byte *hit_data = contents + offset;
451   bfd_vma reloc_bits, check;
452 
453   switch (r_type)
454     {
455      case R_CRX_IMM16:
456      case R_CRX_IMM32:
457      case R_CRX_ABS16:
458      case R_CRX_ABS32:
459      case R_CRX_REL8_CMP:
460      case R_CRX_REL16:
461      case R_CRX_REL24:
462      case R_CRX_REL32:
463      case R_CRX_REGREL12:
464      case R_CRX_REGREL22:
465      case R_CRX_REGREL28:
466      case R_CRX_REGREL32:
467        /* 'hit_data' is relative to the start of the instruction, not the
468 	  relocation offset. Advance it to account for the exact offset.  */
469        hit_data += 2;
470        break;
471 
472      case R_CRX_REL4:
473        /* This relocation type is used only in 'Branch if Equal to 0'
474 	  instructions and requires special handling.  */
475        Rvalue -= 1;
476        break;
477 
478      case R_CRX_NONE:
479        return bfd_reloc_ok;
480        break;
481 
482      case R_CRX_SWITCH8:
483      case R_CRX_SWITCH16:
484      case R_CRX_SWITCH32:
485        /* We only care about the addend, where the difference between
486 	  expressions is kept.  */
487        Rvalue = 0;
488 
489      default:
490        break;
491     }
492 
493   if (howto->pc_relative)
494     {
495       /* Subtract the address of the section containing the location.  */
496       Rvalue -= (input_section->output_section->vma
497 		 + input_section->output_offset);
498       /* Subtract the position of the location within the section.  */
499       Rvalue -= offset;
500     }
501 
502   /* Add in supplied addend.  */
503   Rvalue += addend;
504 
505   /* Complain if the bitfield overflows, whether it is considered
506      as signed or unsigned.  */
507   check = Rvalue >> howto->rightshift;
508 
509   reloc_bits = ((bfd_vma) 1 << (howto->bitsize - 1) << 1) - 1;
510 
511   if ((check & ~reloc_bits) != 0
512       && (check & ~reloc_bits) != ((bfd_vma) -1 & ~reloc_bits))
513     {
514       /* The above right shift is incorrect for a signed
515 	 value.  See if turning on the upper bits fixes the
516 	 overflow.  */
517       if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
518 	{
519 	  check |= (bfd_vma) -1 & ~((bfd_vma) -1 >> howto->rightshift);
520 	  if ((check & ~reloc_bits) != ((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 >>= howto->rightshift;
529 
530   /* Apply dst_mask to select only relocatable part of the insn.  */
531   Rvalue &= howto->dst_mask;
532 
533   switch (bfd_get_reloc_size (howto))
534     {
535      case 1:
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 2:
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 4:
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 bool
elf32_crx_relax_delete_bytes(struct bfd_link_info * link_info,bfd * abfd,asection * sec,bfd_vma addr,int count)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 *
elf32_crx_get_relocated_section_contents(bfd * output_bfd,struct bfd_link_info * link_info,struct bfd_link_order * link_order,bfd_byte * data,bool relocatable,asymbol ** symbols)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 					  bool 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       free (sections);
802       if (symtab_hdr->contents != (unsigned char *) isymbuf)
803 	free (isymbuf);
804       if (elf_section_data (input_section)->relocs != internal_relocs)
805 	free (internal_relocs);
806     }
807 
808   return data;
809 
810  error_return:
811   free (sections);
812   if (symtab_hdr->contents != (unsigned char *) isymbuf)
813     free (isymbuf);
814   if (elf_section_data (input_section)->relocs != internal_relocs)
815     free (internal_relocs);
816   return NULL;
817 }
818 
819 /* Relocate a CRX ELF section.  */
820 
821 static int
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)822 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
823 			    bfd *input_bfd, asection *input_section,
824 			    bfd_byte *contents, Elf_Internal_Rela *relocs,
825 			    Elf_Internal_Sym *local_syms,
826 			    asection **local_sections)
827 {
828   Elf_Internal_Shdr *symtab_hdr;
829   struct elf_link_hash_entry **sym_hashes;
830   Elf_Internal_Rela *rel, *relend;
831 
832   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
833   sym_hashes = elf_sym_hashes (input_bfd);
834 
835   rel = relocs;
836   relend = relocs + input_section->reloc_count;
837   for (; rel < relend; rel++)
838     {
839       int r_type;
840       reloc_howto_type *howto;
841       unsigned long r_symndx;
842       Elf_Internal_Sym *sym;
843       asection *sec;
844       struct elf_link_hash_entry *h;
845       bfd_vma relocation;
846       bfd_reloc_status_type r;
847 
848       r_symndx = ELF32_R_SYM (rel->r_info);
849       r_type = ELF32_R_TYPE (rel->r_info);
850       howto = crx_elf_howto_table + (r_type);
851 
852       h = NULL;
853       sym = NULL;
854       sec = NULL;
855       if (r_symndx < symtab_hdr->sh_info)
856 	{
857 	  sym = local_syms + r_symndx;
858 	  sec = local_sections[r_symndx];
859 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
860 	}
861       else
862 	{
863 	  bool unresolved_reloc, warned, ignored;
864 
865 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
866 				   r_symndx, symtab_hdr, sym_hashes,
867 				   h, sec, relocation,
868 				   unresolved_reloc, warned, ignored);
869 	}
870 
871       if (sec != NULL && discarded_section (sec))
872 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
873 					 rel, 1, relend, howto, 0, contents);
874 
875       if (bfd_link_relocatable (info))
876 	continue;
877 
878       r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
879 					input_section,
880 					contents, rel->r_offset,
881 					relocation, rel->r_addend,
882 					info, sec, h == NULL);
883 
884       if (r != bfd_reloc_ok)
885 	{
886 	  const char *name;
887 	  const char *msg = (const char *) 0;
888 
889 	  if (h != NULL)
890 	    name = h->root.root.string;
891 	  else
892 	    {
893 	      name = (bfd_elf_string_from_elf_section
894 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
895 	      if (name == NULL || *name == '\0')
896 		name = bfd_section_name (sec);
897 	    }
898 
899 	  switch (r)
900 	    {
901 	     case bfd_reloc_overflow:
902 	       (*info->callbacks->reloc_overflow)
903 		 (info, (h ? &h->root : NULL), name, howto->name,
904 		  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
905 	       break;
906 
907 	     case bfd_reloc_undefined:
908 	       (*info->callbacks->undefined_symbol)
909 		 (info, name, input_bfd, input_section, rel->r_offset, true);
910 	       break;
911 
912 	     case bfd_reloc_outofrange:
913 	       msg = _("internal error: out of range error");
914 	       goto common_error;
915 
916 	     case bfd_reloc_notsupported:
917 	       msg = _("internal error: unsupported relocation error");
918 	       goto common_error;
919 
920 	     case bfd_reloc_dangerous:
921 	       msg = _("internal error: dangerous error");
922 	       goto common_error;
923 
924 	     default:
925 	       msg = _("internal error: unknown error");
926 	       /* Fall through.  */
927 
928 	     common_error:
929 	       (*info->callbacks->warning) (info, msg, name, input_bfd,
930 					    input_section, rel->r_offset);
931 	       break;
932 	    }
933 	}
934     }
935 
936   return true;
937 }
938 
939 /* This function handles relaxing for the CRX.
940 
941    There's quite a few relaxing opportunites available on the CRX:
942 
943 	* bal/bcond:32 -> bal/bcond:16				   2 bytes
944 	* bcond:16 -> bcond:8					   2 bytes
945 	* cmpbcond:24 -> cmpbcond:8				   2 bytes
946 	* arithmetic imm32 -> arithmetic imm16			   2 bytes
947 
948    Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
949 
950 static bool
elf32_crx_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * link_info,bool * again)951 elf32_crx_relax_section (bfd *abfd, asection *sec,
952 			 struct bfd_link_info *link_info, bool *again)
953 {
954   Elf_Internal_Shdr *symtab_hdr;
955   Elf_Internal_Rela *internal_relocs;
956   Elf_Internal_Rela *irel, *irelend;
957   bfd_byte *contents = NULL;
958   Elf_Internal_Sym *isymbuf = NULL;
959 
960   /* Assume nothing changes.  */
961   *again = false;
962 
963   /* We don't have to do anything for a relocatable link, if
964      this section does not have relocs, or if this is not a
965      code section.  */
966   if (bfd_link_relocatable (link_info)
967       || (sec->flags & SEC_RELOC) == 0
968       || sec->reloc_count == 0
969       || (sec->flags & SEC_CODE) == 0)
970     return true;
971 
972   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
973 
974   /* Get a copy of the native relocations.  */
975   internal_relocs = (_bfd_elf_link_read_relocs
976 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
977 		      link_info->keep_memory));
978   if (internal_relocs == NULL)
979     goto error_return;
980 
981   /* Walk through them looking for relaxing opportunities.  */
982   irelend = internal_relocs + sec->reloc_count;
983   for (irel = internal_relocs; irel < irelend; irel++)
984     {
985       bfd_vma symval;
986 
987       /* If this isn't something that can be relaxed, then ignore
988 	 this reloc.  */
989       if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
990 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
991 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
992 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
993 	continue;
994 
995       /* Get the section contents if we haven't done so already.  */
996       if (contents == NULL)
997 	{
998 	  /* Get cached copy if it exists.  */
999 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
1000 	    contents = elf_section_data (sec)->this_hdr.contents;
1001 	  /* Go get them off disk.  */
1002 	  else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1003 	    goto error_return;
1004 	}
1005 
1006       /* Read this BFD's local symbols if we haven't done so already.  */
1007       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1008 	{
1009 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1010 	  if (isymbuf == NULL)
1011 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1012 					    symtab_hdr->sh_info, 0,
1013 					    NULL, NULL, NULL);
1014 	  if (isymbuf == NULL)
1015 	    goto error_return;
1016 	}
1017 
1018       /* Get the value of the symbol referred to by the reloc.  */
1019       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1020 	{
1021 	  /* A local symbol.  */
1022 	  Elf_Internal_Sym *isym;
1023 	  asection *sym_sec;
1024 
1025 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
1026 	  if (isym->st_shndx == SHN_UNDEF)
1027 	    sym_sec = bfd_und_section_ptr;
1028 	  else if (isym->st_shndx == SHN_ABS)
1029 	    sym_sec = bfd_abs_section_ptr;
1030 	  else if (isym->st_shndx == SHN_COMMON)
1031 	    sym_sec = bfd_com_section_ptr;
1032 	  else
1033 	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1034 	  symval = (isym->st_value
1035 		    + sym_sec->output_section->vma
1036 		    + sym_sec->output_offset);
1037 	}
1038       else
1039 	{
1040 	  unsigned long indx;
1041 	  struct elf_link_hash_entry *h;
1042 
1043 	  /* An external symbol.  */
1044 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1045 	  h = elf_sym_hashes (abfd)[indx];
1046 	  BFD_ASSERT (h != NULL);
1047 
1048 	  if (h->root.type != bfd_link_hash_defined
1049 	      && h->root.type != bfd_link_hash_defweak)
1050 	    /* This appears to be a reference to an undefined
1051 	       symbol.  Just ignore it--it will be caught by the
1052 	       regular reloc processing.  */
1053 	    continue;
1054 
1055 	  symval = (h->root.u.def.value
1056 		    + h->root.u.def.section->output_section->vma
1057 		    + h->root.u.def.section->output_offset);
1058 	}
1059 
1060       /* For simplicity of coding, we are going to modify the section
1061 	 contents, the section relocs, and the BFD symbol table.  We
1062 	 must tell the rest of the code not to free up this
1063 	 information.  It would be possible to instead create a table
1064 	 of changes which have to be made, as is done in coff-mips.c;
1065 	 that would be more work, but would require less memory when
1066 	 the linker is run.  */
1067 
1068       /* Try to turn a 32bit pc-relative branch/call into
1069 	 a 16bit pc-relative branch/call.  */
1070       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
1071 	{
1072 	  bfd_vma value = symval;
1073 
1074 	  /* Deal with pc-relative gunk.  */
1075 	  value -= (sec->output_section->vma + sec->output_offset);
1076 	  value -= irel->r_offset;
1077 	  value += irel->r_addend;
1078 
1079 	  /* See if the value will fit in 16 bits, note the high value is
1080 	     0xfffe + 2 as the target will be two bytes closer if we are
1081 	     able to relax.  */
1082 	  if ((long) value < 0x10000 && (long) value > -0x10002)
1083 	    {
1084 	      unsigned short code;
1085 
1086 	      /* Get the opcode.  */
1087 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1088 
1089 	      /* Verify it's a 'bal'/'bcond' and fix the opcode.  */
1090 	      if ((code & 0xfff0) == 0x3170)
1091 		bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1092 	      else if ((code & 0xf0ff) == 0x707f)
1093 		bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
1094 	      else
1095 		continue;
1096 
1097 	      /* Note that we've changed the relocs, section contents, etc.  */
1098 	      elf_section_data (sec)->relocs = internal_relocs;
1099 	      elf_section_data (sec)->this_hdr.contents = contents;
1100 	      symtab_hdr->contents = (unsigned char *) isymbuf;
1101 
1102 	      /* Fix the relocation's type.  */
1103 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1104 					   R_CRX_REL16);
1105 
1106 	      /* Delete two bytes of data.  */
1107 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1108 						   irel->r_offset + 2, 2))
1109 		goto error_return;
1110 
1111 	      /* That will change things, so, we should relax again.
1112 		 Note that this is not required, and it may be slow.  */
1113 	      *again = true;
1114 	    }
1115 	}
1116 
1117       /* Try to turn a 16bit pc-relative branch into an
1118 	 8bit pc-relative branch.  */
1119       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
1120 	{
1121 	  bfd_vma value = symval;
1122 
1123 	  /* Deal with pc-relative gunk.  */
1124 	  value -= (sec->output_section->vma + sec->output_offset);
1125 	  value -= irel->r_offset;
1126 	  value += irel->r_addend;
1127 
1128 	  /* See if the value will fit in 8 bits, note the high value is
1129 	     0xfc + 2 as the target will be two bytes closer if we are
1130 	     able to relax.  */
1131 	  if ((long) value < 0xfe && (long) value > -0x100)
1132 	    {
1133 	      unsigned short code;
1134 
1135 	      /* Get the opcode.  */
1136 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1137 
1138 	      /* Verify it's a 'bcond' opcode.  */
1139 	      if ((code & 0xf0ff) != 0x707e)
1140 		continue;
1141 
1142 	      /* Note that we've changed the relocs, section contents, etc.  */
1143 	      elf_section_data (sec)->relocs = internal_relocs;
1144 	      elf_section_data (sec)->this_hdr.contents = contents;
1145 	      symtab_hdr->contents = (unsigned char *) isymbuf;
1146 
1147 	      /* Fix the relocation's type.  */
1148 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1149 					   R_CRX_REL8);
1150 
1151 	      /* Delete two bytes of data.  */
1152 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1153 						   irel->r_offset + 2, 2))
1154 		goto error_return;
1155 
1156 	      /* That will change things, so, we should relax again.
1157 		 Note that this is not required, and it may be slow.  */
1158 	      *again = true;
1159 	    }
1160 	}
1161 
1162       /* Try to turn a 24bit pc-relative cmp&branch into
1163 	 an 8bit pc-relative cmp&branch.  */
1164       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
1165 	{
1166 	  bfd_vma value = symval;
1167 
1168 	  /* Deal with pc-relative gunk.  */
1169 	  value -= (sec->output_section->vma + sec->output_offset);
1170 	  value -= irel->r_offset;
1171 	  value += irel->r_addend;
1172 
1173 	  /* See if the value will fit in 8 bits, note the high value is
1174 	     0x7e + 2 as the target will be two bytes closer if we are
1175 	     able to relax.  */
1176 	  if ((long) value < 0x100 && (long) value > -0x100)
1177 	    {
1178 	      unsigned short code;
1179 
1180 	      /* Get the opcode.  */
1181 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1182 
1183 	      /* Verify it's a 'cmp&branch' opcode.  */
1184 	      if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
1185 	       && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
1186 	       && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
1187 	       /* Or a Co-processor branch ('bcop').  */
1188 	       && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
1189 		continue;
1190 
1191 	      /* Note that we've changed the relocs, section contents, etc.  */
1192 	      elf_section_data (sec)->relocs = internal_relocs;
1193 	      elf_section_data (sec)->this_hdr.contents = contents;
1194 	      symtab_hdr->contents = (unsigned char *) isymbuf;
1195 
1196 	      /* Fix the opcode.  */
1197 	      bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
1198 
1199 	      /* Fix the relocation's type.  */
1200 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1201 					   R_CRX_REL8_CMP);
1202 
1203 	      /* Delete two bytes of data.  */
1204 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1205 						   irel->r_offset + 4, 2))
1206 		goto error_return;
1207 
1208 	      /* That will change things, so, we should relax again.
1209 		 Note that this is not required, and it may be slow.  */
1210 	      *again = true;
1211 	    }
1212 	}
1213 
1214       /* Try to turn a 32bit immediate address into
1215 	 a 16bit immediate address.  */
1216       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
1217 	{
1218 	  bfd_vma value = symval;
1219 
1220 	  /* See if the value will fit in 16 bits.  */
1221 	  if ((long) value < 0x7fff && (long) value > -0x8000)
1222 	    {
1223 	      unsigned short code;
1224 
1225 	      /* Get the opcode.  */
1226 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1227 
1228 	      /* Verify it's a 'arithmetic double'.  */
1229 	      if ((code & 0xf0f0) != 0x20f0)
1230 		continue;
1231 
1232 	      /* Note that we've changed the relocs, section contents, etc.  */
1233 	      elf_section_data (sec)->relocs = internal_relocs;
1234 	      elf_section_data (sec)->this_hdr.contents = contents;
1235 	      symtab_hdr->contents = (unsigned char *) isymbuf;
1236 
1237 	      /* Fix the opcode.  */
1238 	      bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
1239 
1240 	      /* Fix the relocation's type.  */
1241 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1242 					   R_CRX_IMM16);
1243 
1244 	      /* Delete two bytes of data.  */
1245 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
1246 						   irel->r_offset + 2, 2))
1247 		goto error_return;
1248 
1249 	      /* That will change things, so, we should relax again.
1250 		 Note that this is not required, and it may be slow.  */
1251 	      *again = true;
1252 	    }
1253 	}
1254     }
1255 
1256   if (isymbuf != NULL
1257       && symtab_hdr->contents != (unsigned char *) isymbuf)
1258     {
1259       if (! link_info->keep_memory)
1260 	free (isymbuf);
1261       else
1262 	{
1263 	  /* Cache the symbols for elf_link_input_bfd.  */
1264 	  symtab_hdr->contents = (unsigned char *) isymbuf;
1265 	}
1266     }
1267 
1268   if (contents != NULL
1269       && elf_section_data (sec)->this_hdr.contents != contents)
1270     {
1271       if (! link_info->keep_memory)
1272 	free (contents);
1273       else
1274 	{
1275 	  /* Cache the section contents for elf_link_input_bfd.  */
1276 	  elf_section_data (sec)->this_hdr.contents = contents;
1277 	}
1278     }
1279 
1280   if (elf_section_data (sec)->relocs != internal_relocs)
1281     free (internal_relocs);
1282 
1283   return true;
1284 
1285  error_return:
1286   if (symtab_hdr->contents != (unsigned char *) isymbuf)
1287     free (isymbuf);
1288   if (elf_section_data (sec)->this_hdr.contents != contents)
1289     free (contents);
1290   if (elf_section_data (sec)->relocs != internal_relocs)
1291     free (internal_relocs);
1292 
1293   return false;
1294 }
1295 
1296 /* Definitions for setting CRX target vector.  */
1297 #define TARGET_LITTLE_SYM		crx_elf32_vec
1298 #define TARGET_LITTLE_NAME		"elf32-crx"
1299 #define ELF_ARCH			bfd_arch_crx
1300 #define ELF_MACHINE_CODE		EM_CRX
1301 #define ELF_MAXPAGESIZE			0x1
1302 #define elf_symbol_leading_char		'_'
1303 
1304 #define bfd_elf32_bfd_reloc_type_lookup	elf_crx_reloc_type_lookup
1305 #define bfd_elf32_bfd_reloc_name_lookup \
1306 					elf_crx_reloc_name_lookup
1307 #define elf_info_to_howto		elf_crx_info_to_howto
1308 #define elf_info_to_howto_rel		NULL
1309 #define elf_backend_relocate_section	elf32_crx_relocate_section
1310 #define bfd_elf32_bfd_relax_section	elf32_crx_relax_section
1311 #define bfd_elf32_bfd_get_relocated_section_contents \
1312 				elf32_crx_get_relocated_section_contents
1313 #define elf_backend_can_gc_sections     1
1314 #define elf_backend_rela_normal		1
1315 
1316 #include "elf32-target.h"
1317