xref: /netbsd-src/external/gpl3/binutils/dist/bfd/elf32-ft32.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* ft32-specific support for 32-bit ELF.
2    Copyright (C) 2013-2024 Free Software Foundation, Inc.
3 
4    Copied from elf32-moxie.c which is..
5    Copyright (C) 2009-2024 Free Software Foundation, Inc.
6    Free Software Foundation, Inc.
7 
8    This file is part of BFD, the Binary File Descriptor library.
9 
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23    MA 02110-1301, USA.  */
24 
25 #include "sysdep.h"
26 #include "bfd.h"
27 #include "libbfd.h"
28 #include "elf-bfd.h"
29 #include "elf/ft32.h"
30 #include "opcode/ft32.h"
31 
32 static bool debug_relax = false;
33 
34 static bfd_reloc_status_type
35 bfd_elf_ft32_diff_reloc (bfd *, arelent *, asymbol *, void *,
36 			asection *, bfd *, char **);
37 
38 static reloc_howto_type ft32_elf_howto_table [] =
39 {
40   /* This reloc does nothing.  */
41   HOWTO (R_FT32_NONE,		/* type */
42 	 0,			/* rightshift */
43 	 0,			/* size */
44 	 0,			/* bitsize */
45 	 false,			/* pc_relative */
46 	 0,			/* bitpos */
47 	 complain_overflow_dont, /* complain_on_overflow */
48 	 bfd_elf_generic_reloc,	/* special_function */
49 	 "R_FT32_NONE",		/* name */
50 	 false,			/* partial_inplace */
51 	 0,			/* src_mask */
52 	 0,			/* dst_mask */
53 	 false),		/* pcrel_offset */
54 
55   /* A 32 bit absolute relocation.  */
56 
57   HOWTO (R_FT32_32,		/* type */
58 	 0,			/* rightshift */
59 	 4,			/* size */
60 	 32,			/* bitsize */
61 	 false,			/* pc_relative */
62 	 0,			/* bitpos */
63 	 complain_overflow_bitfield, /* complain_on_overflow */
64 	 bfd_elf_generic_reloc,	/* special_function */
65 	 "R_FT32_32",		/* name */
66 	 false,			/* partial_inplace */
67 	 0x00000000,		/* src_mask */
68 	 0xffffffff,		/* dst_mask */
69 	 false),		/* pcrel_offset */
70 
71   HOWTO (R_FT32_16,		/* type */
72 	 0,			/* rightshift */
73 	 2,			/* size */
74 	 16,			/* bitsize */
75 	 false,			/* pc_relative */
76 	 0,			/* bitpos */
77 	 complain_overflow_dont, /* complain_on_overflow */
78 	 bfd_elf_generic_reloc,	/* special_function */
79 	 "R_FT32_16",		/* name */
80 	 false,			/* partial_inplace */
81 	 0x00000000,		/* src_mask */
82 	 0x0000ffff,		/* dst_mask */
83 	 false),		/* pcrel_offset */
84 
85   HOWTO (R_FT32_8,		/* type */
86 	 0,			/* rightshift */
87 	 1,			/* size */
88 	 8,			/* bitsize */
89 	 false,			/* pc_relative */
90 	 0,			/* bitpos */
91 	 complain_overflow_signed, /* complain_on_overflow */
92 	 bfd_elf_generic_reloc,	/* special_function */
93 	 "R_FT32_8",		/* name */
94 	 false,			/* partial_inplace */
95 	 0x00000000,		/* src_mask */
96 	 0x000000ff,		/* dst_mask */
97 	 false),		/* pcrel_offset */
98 
99   HOWTO (R_FT32_10,		/* type */
100 	 0,			/* rightshift */
101 	 2,			/* size */
102 	 10,			/* bitsize */
103 	 false,			/* pc_relative */
104 	 4,			/* bitpos */
105 	 complain_overflow_bitfield, /* complain_on_overflow */
106 	 bfd_elf_generic_reloc,	/* special_function */
107 	 "R_FT32_10",		/* name */
108 	 false,			/* partial_inplace */
109 	 0x00000000,		/* src_mask */
110 	 0x00003ff0,		/* dst_mask */
111 	 false),		/* pcrel_offset */
112 
113   HOWTO (R_FT32_20,		/* type */
114 	 0,			/* rightshift */
115 	 4,			/* size */
116 	 20,			/* bitsize */
117 	 false,			/* pc_relative */
118 	 0,			/* bitpos */
119 	 complain_overflow_dont, /* complain_on_overflow */
120 	 bfd_elf_generic_reloc,	/* special_function */
121 	 "R_FT32_20",		/* name */
122 	 false,			/* partial_inplace */
123 	 0x00000000,		/* src_mask */
124 	 0x000fffff,		/* dst_mask */
125 	 false),		/* pcrel_offset */
126 
127   HOWTO (R_FT32_17,		/* type */
128 	 0,			/* rightshift */
129 	 4,			/* size */
130 	 17,			/* bitsize */
131 	 false,			/* pc_relative */
132 	 0,			/* bitpos */
133 	 complain_overflow_dont, /* complain_on_overflow */
134 	 bfd_elf_generic_reloc,	/* special_function */
135 	 "R_FT32_17",		/* name */
136 	 false,			/* partial_inplace */
137 	 0x00000000,		/* src_mask */
138 	 0x0001ffff,		/* dst_mask */
139 	 false),		/* pcrel_offset */
140 
141   HOWTO (R_FT32_18,		/* type */
142 	 2,			/* rightshift */
143 	 4,			/* size */
144 	 18,			/* bitsize */
145 	 false,			/* pc_relative */
146 	 0,			/* bitpos */
147 	 complain_overflow_dont, /* complain_on_overflow */
148 	 bfd_elf_generic_reloc,	/* special_function */
149 	 "R_FT32_18",		/* name */
150 	 false,			/* partial_inplace */
151 	 0x00000000,		/* src_mask */
152 	 0x0003ffff,		/* dst_mask */
153 	 false),		/* pcrel_offset */
154 
155   HOWTO (R_FT32_RELAX,		/* type */
156 	 0,			/* rightshift */
157 	 2,			/* size */
158 	 10,			/* bitsize */
159 	 false,			/* pc_relative */
160 	 4,			/* bitpos */
161 	 complain_overflow_signed, /* complain_on_overflow */
162 	 bfd_elf_generic_reloc,	/* special_function */
163 	 "R_FT32_RELAX",	/* name */
164 	 false,			/* partial_inplace */
165 	 0x00000000,		/* src_mask */
166 	 0x00000000,		/* dst_mask */
167 	 false),		/* pcrel_offset */
168 
169   HOWTO (R_FT32_SC0,		/* type */
170 	 0,			/* rightshift */
171 	 2,			/* size */
172 	 10,			/* bitsize */
173 	 false,			/* pc_relative */
174 	 4,			/* bitpos */
175 	 complain_overflow_signed, /* complain_on_overflow */
176 	 bfd_elf_generic_reloc,	/* special_function */
177 	 "R_FT32_SC0",		/* name */
178 	 false,			/* partial_inplace */
179 	 0x00000000,		/* src_mask */
180 	 0x00000000,		/* dst_mask */
181 	 false),		/* pcrel_offset */
182   HOWTO (R_FT32_SC1,		/* type */
183 	 2,			/* rightshift */
184 	 4,			/* size */
185 	 22,			/* bitsize */
186 	 true,			/* pc_relative */
187 	 7,			/* bitpos */
188 	 complain_overflow_dont, /* complain_on_overflow */
189 	 bfd_elf_generic_reloc,	/* special_function */
190 	 "R_FT32_SC1",		/* name */
191 	 true,			/* partial_inplace */
192 	 0x07ffff80,		/* src_mask */
193 	 0x07ffff80,		/* dst_mask */
194 	 false),		/* pcrel_offset */
195   HOWTO (R_FT32_15,		/* type */
196 	 0,			/* rightshift */
197 	 4,			/* size */
198 	 15,			/* bitsize */
199 	 false,			/* pc_relative */
200 	 0,			/* bitpos */
201 	 complain_overflow_dont, /* complain_on_overflow */
202 	 bfd_elf_generic_reloc,	/* special_function */
203 	 "R_FT32_15",		/* name */
204 	 false,			/* partial_inplace */
205 	 0x00000000,		/* src_mask */
206 	 0x00007fff,		/* dst_mask */
207 	 false),		/* pcrel_offset */
208   HOWTO (R_FT32_DIFF32,		/* type */
209 	 0,			/* rightshift */
210 	 4,			/* size */
211 	 32,			/* bitsize */
212 	 false,			/* pc_relative */
213 	 0,			/* bitpos */
214 	 complain_overflow_dont, /* complain_on_overflow */
215 	 bfd_elf_ft32_diff_reloc, /* special_function */
216 	 "R_FT32_DIFF32",	/* name */
217 	 false,			/* partial_inplace */
218 	 0,			/* src_mask */
219 	 0xffffffff,		/* dst_mask */
220 	 false),		/* pcrel_offset */
221 };
222 
223 /* Map BFD reloc types to FT32 ELF reloc types.  */
224 
225 struct ft32_reloc_map
226 {
227   bfd_reloc_code_real_type bfd_reloc_val;
228   unsigned int ft32_reloc_val;
229 };
230 
231 static const struct ft32_reloc_map ft32_reloc_map [] =
232 {
233   { BFD_RELOC_NONE,		R_FT32_NONE },
234   { BFD_RELOC_32,		R_FT32_32 },
235   { BFD_RELOC_16,		R_FT32_16 },
236   { BFD_RELOC_8,		R_FT32_8 },
237   { BFD_RELOC_FT32_10,		R_FT32_10 },
238   { BFD_RELOC_FT32_20,		R_FT32_20 },
239   { BFD_RELOC_FT32_17,		R_FT32_17 },
240   { BFD_RELOC_FT32_18,		R_FT32_18 },
241   { BFD_RELOC_FT32_RELAX,	R_FT32_RELAX },
242   { BFD_RELOC_FT32_SC0,		R_FT32_SC0 },
243   { BFD_RELOC_FT32_SC1,		R_FT32_SC1 },
244   { BFD_RELOC_FT32_15,		R_FT32_15 },
245   { BFD_RELOC_FT32_DIFF32,	R_FT32_DIFF32 },
246 };
247 
248 /* Perform a diff relocation. Nothing to do, as the difference value is
249    already written into the section's contents. */
250 
251 static bfd_reloc_status_type
bfd_elf_ft32_diff_reloc(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry ATTRIBUTE_UNUSED,asymbol * symbol ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd ATTRIBUTE_UNUSED,char ** error_message ATTRIBUTE_UNUSED)252 bfd_elf_ft32_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED,
253 		      arelent *reloc_entry ATTRIBUTE_UNUSED,
254 	      asymbol *symbol ATTRIBUTE_UNUSED,
255 	      void *data ATTRIBUTE_UNUSED,
256 	      asection *input_section ATTRIBUTE_UNUSED,
257 	      bfd *output_bfd ATTRIBUTE_UNUSED,
258 	      char **error_message ATTRIBUTE_UNUSED)
259 {
260   return bfd_reloc_ok;
261 }
262 
263 static reloc_howto_type *
ft32_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)264 ft32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
265 			 bfd_reloc_code_real_type code)
266 {
267   unsigned int i;
268 
269   for (i = 0; i < sizeof (ft32_reloc_map) / sizeof (ft32_reloc_map[0]); i++)
270     if (ft32_reloc_map [i].bfd_reloc_val == code)
271       return & ft32_elf_howto_table [ft32_reloc_map[i].ft32_reloc_val];
272 
273   return NULL;
274 }
275 
276 static reloc_howto_type *
ft32_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)277 ft32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
278 {
279   unsigned int i;
280 
281   for (i = 0;
282        i < sizeof (ft32_elf_howto_table) / sizeof (ft32_elf_howto_table[0]);
283        i++)
284     if (ft32_elf_howto_table[i].name != NULL
285 	&& strcasecmp (ft32_elf_howto_table[i].name, r_name) == 0)
286       return &ft32_elf_howto_table[i];
287 
288   return NULL;
289 }
290 
291 /* Set the howto pointer for an FT32 ELF reloc.  */
292 
293 static bool
ft32_info_to_howto_rela(bfd * abfd,arelent * cache_ptr,Elf_Internal_Rela * dst)294 ft32_info_to_howto_rela (bfd *abfd,
295 			  arelent *cache_ptr,
296 			  Elf_Internal_Rela *dst)
297 {
298   unsigned int r_type;
299 
300   r_type = ELF32_R_TYPE (dst->r_info);
301   if (r_type >= (unsigned int) R_FT32_max)
302     {
303       /* xgettext:c-format */
304       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
305 			  abfd, r_type);
306       bfd_set_error (bfd_error_bad_value);
307       return false;
308     }
309 
310   cache_ptr->howto = & ft32_elf_howto_table [r_type];
311   return cache_ptr->howto != NULL;
312 }
313 
314 /* Relocate an FT32 ELF section.
315 
316    The RELOCATE_SECTION function is called by the new ELF backend linker
317    to handle the relocations for a section.
318 
319    The relocs are always passed as Rela structures; if the section
320    actually uses Rel structures, the r_addend field will always be
321    zero.
322 
323    This function is responsible for adjusting the section contents as
324    necessary, and (if using Rela relocs and generating a relocatable
325    output file) adjusting the reloc addend as necessary.
326 
327    This function does not have to worry about setting the reloc
328    address or the reloc symbol index.
329 
330    LOCAL_SYMS is a pointer to the swapped in local symbols.
331 
332    LOCAL_SECTIONS is an array giving the section in the input file
333    corresponding to the st_shndx field of each local symbol.
334 
335    The global hash table entry for the global symbols can be found
336    via elf_sym_hashes (input_bfd).
337 
338    When generating relocatable output, this function must handle
339    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
340    going to be the section symbol corresponding to the output
341    section, which means that the addend must be adjusted
342    accordingly.  */
343 
344 static int
ft32_elf_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)345 ft32_elf_relocate_section (bfd *output_bfd,
346 			    struct bfd_link_info *info,
347 			    bfd *input_bfd,
348 			    asection *input_section,
349 			    bfd_byte *contents,
350 			    Elf_Internal_Rela *relocs,
351 			    Elf_Internal_Sym *local_syms,
352 			    asection **local_sections)
353 {
354   Elf_Internal_Shdr *symtab_hdr;
355   struct elf_link_hash_entry **sym_hashes;
356   Elf_Internal_Rela *rel;
357   Elf_Internal_Rela *relend;
358 
359   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
360   sym_hashes = elf_sym_hashes (input_bfd);
361   relend     = relocs + input_section->reloc_count;
362 
363   for (rel = relocs; rel < relend; rel ++)
364     {
365       reloc_howto_type *howto;
366       unsigned long r_symndx;
367       Elf_Internal_Sym *sym;
368       asection *sec;
369       struct elf_link_hash_entry *h;
370       bfd_vma relocation;
371       bfd_reloc_status_type r;
372       const char *name;
373       int r_type;
374 
375       r_type = ELF32_R_TYPE (rel->r_info);
376       r_symndx = ELF32_R_SYM (rel->r_info);
377       howto  = ft32_elf_howto_table + r_type;
378       h      = NULL;
379       sym    = NULL;
380       sec    = NULL;
381 
382       if (r_symndx < symtab_hdr->sh_info)
383 	{
384 	  sym = local_syms + r_symndx;
385 	  sec = local_sections [r_symndx];
386 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
387 
388 	  name = bfd_elf_string_from_elf_section
389 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
390 	  name = name == NULL ? bfd_section_name (sec) : name;
391 	}
392       else
393 	{
394 	  bool unresolved_reloc, warned, ignored;
395 
396 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
397 				   r_symndx, symtab_hdr, sym_hashes,
398 				   h, sec, relocation,
399 				   unresolved_reloc, warned, ignored);
400 
401 	  name = h->root.root.string;
402 	}
403 
404       if (sec != NULL && discarded_section (sec))
405 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
406 					 rel, 1, relend, howto, 0, contents);
407 
408       if (bfd_link_relocatable (info))
409 	continue;
410 
411       switch (howto->type)
412 	{
413 	  case R_FT32_SC0:
414 	    {
415 	      unsigned int insn;
416 	      int offset;
417 	      unsigned int code15[2];
418 
419 	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
420 	      ft32_split_shortcode (insn, code15);
421 
422 	      offset = (int)relocation;
423 	      offset += (int)(rel->r_addend - rel->r_offset);
424 	      offset -= (input_section->output_section->vma +
425 			 input_section->output_offset);
426 	      if ((offset < -1024) || (offset >= 1024))
427 		{
428 		  r = bfd_reloc_outofrange;
429 		  break;
430 		}
431 	      code15[0] |= ((offset / 4) & 511);
432 	      insn = ft32_merge_shortcode (code15);
433 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
434 	    }
435 	    r = bfd_reloc_ok;
436 	    break;
437 
438 	  case R_FT32_SC1:
439 	    {
440 	      unsigned int insn;
441 	      int offset;
442 	      unsigned int code15[2];
443 
444 	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
445 	      ft32_split_shortcode (insn, code15);
446 
447 	      offset = (int)relocation;
448 	      offset += (int)(rel->r_addend - rel->r_offset);
449 	      offset -= (input_section->output_section->vma +
450 			 input_section->output_offset);
451 	      if ((offset < -1024) || (offset >= 1024))
452 		{
453 		  r = bfd_reloc_outofrange;
454 		  break;
455 		}
456 	      code15[1] |= ((offset / 4) & 511);
457 	      insn = ft32_merge_shortcode (code15);
458 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
459 	    }
460 	    r = bfd_reloc_ok;
461 	    break;
462 
463 	  case R_FT32_DIFF32:
464 	    r = bfd_reloc_ok;
465 	    break;
466 
467 	  default:
468 	    r = _bfd_final_link_relocate (howto, input_bfd, input_section,
469 					  contents, rel->r_offset,
470 					  relocation, rel->r_addend);
471 	    break;
472 	}
473 
474       if (r != bfd_reloc_ok)
475 	{
476 	  const char * msg = NULL;
477 
478 	  switch (r)
479 	    {
480 	    case bfd_reloc_overflow:
481 	      (*info->callbacks->reloc_overflow)
482 		(info, (h ? &h->root : NULL), name, howto->name,
483 		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
484 	      break;
485 
486 	    case bfd_reloc_undefined:
487 	      (*info->callbacks->undefined_symbol)
488 		(info, name, input_bfd, input_section, rel->r_offset, true);
489 	      break;
490 
491 	    case bfd_reloc_outofrange:
492 	      msg = _("internal error: out of range error");
493 	      break;
494 
495 	    case bfd_reloc_notsupported:
496 	      msg = _("internal error: unsupported relocation error");
497 	      break;
498 
499 	    case bfd_reloc_dangerous:
500 	      msg = _("internal error: dangerous relocation");
501 	      break;
502 
503 	    default:
504 	      msg = _("internal error: unknown error");
505 	      break;
506 	    }
507 
508 	  if (msg)
509 	    (*info->callbacks->warning) (info, msg, name, input_bfd,
510 					 input_section, rel->r_offset);
511 	}
512     }
513 
514   return true;
515 }
516 
517 /* Relaxation.  */
518 
519 static bool
ft32_reloc_shortable(bfd * abfd,asection * sec,Elf_Internal_Sym * isymbuf ATTRIBUTE_UNUSED,bfd_byte * contents,bfd_vma pc ATTRIBUTE_UNUSED,Elf_Internal_Rela * irel,unsigned int * sc)520 ft32_reloc_shortable
521     (bfd *		    abfd,
522      asection *		    sec,
523      Elf_Internal_Sym *	    isymbuf ATTRIBUTE_UNUSED,
524      bfd_byte *		    contents,
525      bfd_vma		    pc ATTRIBUTE_UNUSED,
526      Elf_Internal_Rela *    irel,
527      unsigned int *	    sc)
528 {
529   Elf_Internal_Shdr *symtab_hdr ATTRIBUTE_UNUSED;
530   bfd_vma symval;
531 
532   enum elf_ft32_reloc_type r_type;
533   reloc_howto_type *howto = NULL;
534   unsigned int insn;
535   int offset;
536   bfd_vma dot, value;
537 
538   r_type = ELF32_R_TYPE (irel->r_info);
539   howto = &ft32_elf_howto_table [r_type];
540 
541   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
542 
543   /* Get the value of the symbol referred to by the reloc.  */
544   if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
545     {
546       /* A local symbol.  */
547       Elf_Internal_Sym *isym;
548       asection *sym_sec;
549 
550       isym = isymbuf + ELF32_R_SYM (irel->r_info);
551       sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
552       symval = isym->st_value;
553       /* If the reloc is absolute, it will not have
554 	 a symbol or section associated with it.  */
555       if (sym_sec)
556 	symval += sym_sec->output_section->vma
557 	  + sym_sec->output_offset;
558     }
559   else
560     {
561       unsigned long indx;
562       struct elf_link_hash_entry *h;
563 
564       /* An external symbol.  */
565       indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
566       h = elf_sym_hashes (abfd)[indx];
567       BFD_ASSERT (h != NULL);
568       if (h->root.type != bfd_link_hash_defined
569 	  && h->root.type != bfd_link_hash_defweak)
570 	/* This appears to be a reference to an undefined
571 	   symbol.  Just ignore it--it will be caught by the
572 	   regular reloc processing.  */
573 	return false;
574 
575       symval = (h->root.u.def.value
576 		+ h->root.u.def.section->output_section->vma
577 		+ h->root.u.def.section->output_offset);
578     }
579 
580   switch (r_type)
581     {
582       case R_FT32_8:
583       case R_FT32_10:
584       case R_FT32_16:
585       case R_FT32_20:
586       case R_FT32_RELAX:
587 	if (symval != 0)
588 	  return false;
589 	insn = bfd_get_32 (abfd, contents + irel->r_offset);
590 	insn |= ((symval + irel->r_addend) << howto->bitpos) & howto->dst_mask;
591 	return ft32_shortcode (insn, sc);
592 
593       case R_FT32_18:
594 	insn = bfd_get_32 (abfd, contents + irel->r_offset);
595 	/* Get the address of this instruction.  */
596 	dot = (sec->output_section->vma
597 	       + sec->output_offset + irel->r_offset);
598 	value = symval + irel->r_addend;
599 	offset = (value - dot) / 4;
600 
601 	if ((dot > 0x8c) && (-256 <= offset) && (offset < 256))
602 	  {
603 	    switch (insn)
604 	      {
605 		case 0x00200000: *sc = (3 << 13) | (0  << 9); return true;
606 		case 0x00280000: *sc = (3 << 13) | (1  << 9); return true;
607 		case 0x00600000: *sc = (3 << 13) | (2  << 9); return true;
608 		case 0x00680000: *sc = (3 << 13) | (3  << 9); return true;
609 		case 0x00a00000: *sc = (3 << 13) | (4  << 9); return true;
610 		case 0x00a80000: *sc = (3 << 13) | (5  << 9); return true;
611 		case 0x00e00000: *sc = (3 << 13) | (6  << 9); return true;
612 		case 0x00e80000: *sc = (3 << 13) | (7  << 9); return true;
613 		case 0x01200000: *sc = (3 << 13) | (8  << 9); return true;
614 		case 0x01280000: *sc = (3 << 13) | (9  << 9); return true;
615 		case 0x01600000: *sc = (3 << 13) | (10 << 9); return true;
616 		case 0x01680000: *sc = (3 << 13) | (11 << 9); return true;
617 		case 0x01a00000: *sc = (3 << 13) | (12 << 9); return true;
618 		case 0x01a80000: *sc = (3 << 13) | (13 << 9); return true;
619 
620 		case 0x00300000: *sc = (3 << 13) | (14 << 9); return true;
621 		case 0x00340000: *sc = (3 << 13) | (15 << 9); return true;
622 
623 		default:
624 		  break;
625 	      }
626 	  }
627 	break;
628 
629       default:
630 	break;
631     }
632   return false;
633 }
634 
635 /* Returns whether the relocation type passed is a diff reloc.  */
636 
637 static bool
elf32_ft32_is_diff_reloc(Elf_Internal_Rela * irel)638 elf32_ft32_is_diff_reloc (Elf_Internal_Rela *irel)
639 {
640   return (ELF32_R_TYPE (irel->r_info) == R_FT32_DIFF32);
641 }
642 
643 /* Reduce the diff value written in the section by count if the shrinked
644    insn address happens to fall between the two symbols for which this
645    diff reloc was emitted.  */
646 
647 static bool
elf32_ft32_adjust_diff_reloc_value(bfd * abfd,struct bfd_section * isec,Elf_Internal_Rela * irel,bfd_vma symval,bfd_vma shrinked_insn_address,int count)648 elf32_ft32_adjust_diff_reloc_value (bfd *abfd,
649 				   struct bfd_section *isec,
650 				   Elf_Internal_Rela *irel,
651 				   bfd_vma symval,
652 				   bfd_vma shrinked_insn_address,
653 				   int count)
654 {
655   unsigned char * reloc_contents = NULL;
656   unsigned char * isec_contents = elf_section_data (isec)->this_hdr.contents;
657   bfd_signed_vma x = 0;
658   bfd_vma sym2_address;
659   bfd_vma sym1_address;
660   bfd_vma start_address;
661   bfd_vma end_address;
662 
663 
664   if (isec_contents == NULL)
665     {
666       if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents))
667 	return false;
668 
669       elf_section_data (isec)->this_hdr.contents = isec_contents;
670     }
671 
672   reloc_contents = isec_contents + irel->r_offset;
673 
674   /* Read value written in object file.  */
675   switch (ELF32_R_TYPE (irel->r_info))
676     {
677     case R_FT32_DIFF32:
678       x = bfd_get_signed_32 (abfd, reloc_contents);
679       break;
680 
681     default:
682       return false;
683     }
684 
685   /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written
686      into the object file at the reloc offset. sym2's logical value is
687      symval (<start_of_section>) + reloc addend. Compute the start and end
688      addresses and check if the shrinked insn falls between sym1 and sym2.  */
689   sym2_address = symval + irel->r_addend;
690   sym1_address = sym2_address - x;
691 
692   /* Don't assume sym2 is bigger than sym1 - the difference
693      could be negative. Compute start and end addresses, and
694      use those to see if they span shrinked_insn_address.  */
695   start_address = sym1_address < sym2_address ? sym1_address : sym2_address;
696   end_address = sym1_address > sym2_address ? sym1_address : sym2_address;
697 
698   if (shrinked_insn_address >= start_address
699       && shrinked_insn_address < end_address)
700     {
701       /* Reduce the diff value by count bytes and write it back into section
702 	 contents.  */
703       bfd_signed_vma new_diff = x < 0 ? x + count : x - count;
704 
705       if (sym2_address > shrinked_insn_address)
706 	irel->r_addend -= count;
707 
708       switch (ELF32_R_TYPE (irel->r_info))
709 	{
710 	case R_FT32_DIFF32:
711 	  bfd_put_signed_32 (abfd, new_diff & 0xFFFFFFFF, reloc_contents);
712 	  break;
713 
714 	default:
715 	  return false;
716 	}
717     }
718 
719   return true;
720 }
721 
722 static bool
elf32_ft32_adjust_reloc_if_spans_insn(bfd * abfd,asection * isec,Elf_Internal_Rela * irel,bfd_vma symval,bfd_vma shrinked_insn_address,bfd_vma shrink_boundary,int count)723 elf32_ft32_adjust_reloc_if_spans_insn (bfd *abfd,
724 				      asection *isec,
725 				      Elf_Internal_Rela *irel,  bfd_vma symval,
726 				      bfd_vma shrinked_insn_address,
727 				      bfd_vma shrink_boundary,
728 				      int count)
729 {
730 
731   if (elf32_ft32_is_diff_reloc (irel))
732     {
733       if (!elf32_ft32_adjust_diff_reloc_value (abfd, isec, irel,
734 					       symval,
735 					       shrinked_insn_address,
736 					       count))
737 	return false;
738     }
739   else
740     {
741       bfd_vma reloc_value = symval + irel->r_addend;
742       bool addend_within_shrink_boundary =
743 	(reloc_value <= shrink_boundary);
744       bool reloc_spans_insn =
745 	(symval <= shrinked_insn_address
746 	 && reloc_value > shrinked_insn_address
747 	 && addend_within_shrink_boundary);
748 
749       if (! reloc_spans_insn)
750 	return true;
751 
752       irel->r_addend -= count;
753 
754       if (debug_relax)
755 	printf ("Relocation's addend needed to be fixed \n");
756     }
757   return true;
758 }
759 
760 /* Delete some bytes from a section while relaxing.  */
761 
762 static bool
elf32_ft32_relax_delete_bytes(struct bfd_link_info * link_info,bfd * abfd,asection * sec,bfd_vma addr,int count)763 elf32_ft32_relax_delete_bytes (struct bfd_link_info *link_info, bfd * abfd,
764 			       asection * sec, bfd_vma addr, int count)
765 {
766   Elf_Internal_Shdr *symtab_hdr;
767   unsigned int sec_shndx;
768   bfd_byte *contents;
769   Elf_Internal_Rela *irel, *irelend;
770   bfd_vma toaddr;
771   Elf_Internal_Sym *isym;
772   Elf_Internal_Sym *isymend;
773   struct elf_link_hash_entry **sym_hashes;
774   struct elf_link_hash_entry **end_hashes;
775   struct elf_link_hash_entry **start_hashes;
776   unsigned int symcount;
777   Elf_Internal_Sym *isymbuf = NULL;
778 
779   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
780   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
781 
782   contents = elf_section_data (sec)->this_hdr.contents;
783 
784   toaddr = sec->size;
785 
786   irel = elf_section_data (sec)->relocs;
787   irelend = irel + sec->reloc_count;
788 
789   /* Actually delete the bytes.  */
790   memmove (contents + addr, contents + addr + count,
791 	   (size_t) (toaddr - addr - count));
792   sec->size -= count;
793 
794   /* Adjust all the relocs.  */
795   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
796     /* Get the new reloc address.  */
797     if ((irel->r_offset > addr && irel->r_offset < toaddr))
798       irel->r_offset -= count;
799 
800   /* The reloc's own addresses are now ok. However, we need to readjust
801      the reloc's addend, i.e. the reloc's value if two conditions are met:
802      1.) the reloc is relative to a symbol in this section that
803      is located in front of the shrinked instruction
804      2.) symbol plus addend end up behind the shrinked instruction.
805 
806      The most common case where this happens are relocs relative to
807      the section-start symbol.
808 
809      This step needs to be done for all of the sections of the bfd.  */
810   {
811     struct bfd_section *isec;
812 
813     for (isec = abfd->sections; isec; isec = isec->next)
814       {
815 	bfd_vma symval;
816 	bfd_vma shrinked_insn_address;
817 
818 	if (isec->reloc_count == 0)
819 	  continue;
820 
821 	shrinked_insn_address = (sec->output_section->vma
822 				 + sec->output_offset + addr - count);
823 
824 	irel = elf_section_data (isec)->relocs;
825 	/* PR 12161: Read in the relocs for this section if necessary.  */
826 	if (irel == NULL)
827 	  irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, true);
828 
829 	for (irelend = irel + isec->reloc_count; irel < irelend; irel++)
830 	  {
831 	    /* Read this BFD's local symbols if we haven't done
832 	       so already.  */
833 	    if (isymbuf == NULL && symtab_hdr->sh_info != 0)
834 	      {
835 		isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
836 		if (isymbuf == NULL)
837 		  isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
838 						  symtab_hdr->sh_info, 0,
839 						  NULL, NULL, NULL);
840 		if (isymbuf == NULL)
841 		  return false;
842 	      }
843 
844 	    /* Get the value of the symbol referred to by the reloc.  */
845 	    if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
846 	      {
847 		/* A local symbol.  */
848 		asection *sym_sec;
849 
850 		isym = isymbuf + ELF32_R_SYM (irel->r_info);
851 		sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
852 		symval = isym->st_value;
853 		/* If the reloc is absolute, it will not have
854 		   a symbol or section associated with it.  */
855 		if (sym_sec == sec)
856 		  {
857 		    symval += sym_sec->output_section->vma
858 		      + sym_sec->output_offset;
859 
860 		    if (debug_relax)
861 		      printf ("Checking if the relocation's "
862 			      "addend needs corrections.\n"
863 			      "Address of anchor symbol: 0x%x \n"
864 			      "Address of relocation target: 0x%x \n"
865 			      "Address of relaxed insn: 0x%x \n",
866 			      (unsigned int) symval,
867 			      (unsigned int) (symval + irel->r_addend),
868 			      (unsigned int) shrinked_insn_address);
869 
870 		    if (symval <= shrinked_insn_address
871 			&& (symval + irel->r_addend) > shrinked_insn_address)
872 		      {
873 			/* If there is an alignment boundary, we only need to
874 			   adjust addends that end up below the boundary. */
875 			bfd_vma shrink_boundary = (toaddr
876 						   + sec->output_section->vma
877 						   + sec->output_offset);
878 
879 			if (debug_relax)
880 			  printf
881 			    ("Relocation's addend needed to be fixed \n");
882 
883 			if (!elf32_ft32_adjust_reloc_if_spans_insn (abfd, isec,
884 								    irel, symval,
885 								    shrinked_insn_address,
886 								    shrink_boundary,
887 								    count))
888 			  return false;
889 		      }
890 		  }
891 		/* else reference symbol is absolute. No adjustment needed. */
892 	      }
893 	    /* else...Reference symbol is extern.  No need for adjusting
894 	       the addend.  */
895 	  }
896       }
897   }
898 
899   /* Adjust the local symbols defined in this section.  */
900   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
901   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
902   if (isym)
903     {
904       for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
905 	{
906 	  if (isym->st_shndx == sec_shndx
907 	      && isym->st_value > addr && isym->st_value < toaddr)
908 	    isym->st_value -= count;
909 	}
910     }
911 
912   /* Now adjust the global symbols defined in this section.  */
913   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
914 	      - symtab_hdr->sh_info);
915   sym_hashes = start_hashes = elf_sym_hashes (abfd);
916   end_hashes = sym_hashes + symcount;
917 
918   for (; sym_hashes < end_hashes; sym_hashes++)
919     {
920       struct elf_link_hash_entry *sym_hash = *sym_hashes;
921 
922       /* The '--wrap SYMBOL' option is causing a pain when the object file,
923 	 containing the definition of __wrap_SYMBOL, includes a direct
924 	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
925 	 the same symbol (which is __wrap_SYMBOL), but still exist as two
926 	 different symbols in 'sym_hashes', we don't want to adjust
927 	 the global symbol __wrap_SYMBOL twice.
928 	 This check is only relevant when symbols are being wrapped.  */
929       if (link_info->wrap_hash != NULL)
930 	{
931 	  struct elf_link_hash_entry **cur_sym_hashes;
932 
933 	  /* Loop only over the symbols whom been already checked.  */
934 	  for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
935 	       cur_sym_hashes++)
936 	    /* If the current symbol is identical to 'sym_hash', that means
937 	       the symbol was already adjusted (or at least checked).  */
938 	    if (*cur_sym_hashes == sym_hash)
939 	      break;
940 
941 	  /* Don't adjust the symbol again.  */
942 	  if (cur_sym_hashes < sym_hashes)
943 	    continue;
944 	}
945 
946       if ((sym_hash->root.type == bfd_link_hash_defined
947 	   || sym_hash->root.type == bfd_link_hash_defweak)
948 	  && sym_hash->root.u.def.section == sec
949 	  && sym_hash->root.u.def.value > addr
950 	  && sym_hash->root.u.def.value < toaddr)
951 	sym_hash->root.u.def.value -= count;
952     }
953 
954   return true;
955 }
956 
957 /* Return TRUE if LOC can be a target of a branch, jump or call.  */
958 
959 static bool
elf32_ft32_relax_is_branch_target(struct bfd_link_info * link_info,bfd * abfd,asection * sec,bfd_vma loc)960 elf32_ft32_relax_is_branch_target (struct bfd_link_info *link_info,
961 				   bfd * abfd, asection * sec,
962 				   bfd_vma loc)
963 {
964   Elf_Internal_Shdr *symtab_hdr;
965   Elf_Internal_Rela *irel, *irelend;
966   Elf_Internal_Sym *isym;
967   Elf_Internal_Sym *isymbuf = NULL;
968   bfd_vma symval;
969   struct bfd_section *isec;
970 
971   struct elf_link_hash_entry **sym_hashes;
972   struct elf_link_hash_entry **end_hashes;
973   struct elf_link_hash_entry **start_hashes;
974   unsigned int symcount;
975 
976   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
977 
978   /* Now we check for relocations pointing to ret.  */
979   for (isec = abfd->sections; isec; isec = isec->next)
980     {
981       irel = elf_section_data (isec)->relocs;
982       if (irel == NULL)
983 	irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, true);
984 
985       irelend = irel + isec->reloc_count;
986 
987       for (; irel < irelend; irel++)
988 	{
989 	  /* Read this BFD's local symbols if we haven't done
990 	     so already.  */
991 	  if (isymbuf == NULL && symtab_hdr->sh_info != 0)
992 	    {
993 	      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
994 	      if (isymbuf == NULL)
995 		isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
996 						symtab_hdr->sh_info, 0,
997 						NULL, NULL, NULL);
998 	      if (isymbuf == NULL)
999 		return false;
1000 	    }
1001 
1002 	  /* Get the value of the symbol referred to by the reloc.  */
1003 	  if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1004 	    {
1005 	      /* A local symbol.  */
1006 	      asection *sym_sec;
1007 
1008 	      isym = isymbuf + ELF32_R_SYM (irel->r_info);
1009 	      sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1010 	      symval = isym->st_value;
1011 	      /* If the reloc is absolute, it will not have
1012 		 a symbol or section associated with it.  */
1013 	      if (sym_sec == sec)
1014 		{
1015 		  symval += sym_sec->output_section->vma
1016 			    + sym_sec->output_offset;
1017 
1018 		  if (debug_relax)
1019 		    printf ("0x%x: Address of anchor symbol: 0x%x "
1020 			    "Address of relocation target: 0x%x \n",
1021 			    (unsigned int) irel->r_offset,
1022 			    (unsigned int) symval,
1023 			    (unsigned int) (symval + irel->r_addend));
1024 		  if ((irel->r_addend) == loc)
1025 		    return true;
1026 		}
1027 	    }
1028 	}
1029     }
1030 
1031   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1032 	       - symtab_hdr->sh_info);
1033   sym_hashes = start_hashes = elf_sym_hashes (abfd);
1034   end_hashes = sym_hashes + symcount;
1035 
1036   for (; sym_hashes < end_hashes; sym_hashes++)
1037     {
1038       struct elf_link_hash_entry *sym_hash = *sym_hashes;
1039 
1040       /* The '--wrap SYMBOL' option is causing a pain when the object file,
1041 	 containing the definition of __wrap_SYMBOL, includes a direct
1042 	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
1043 	 the same symbol (which is __wrap_SYMBOL), but still exist as two
1044 	 different symbols in 'sym_hashes', we don't want to adjust
1045 	 the global symbol __wrap_SYMBOL twice.
1046 	 This check is only relevant when symbols are being wrapped.  */
1047       if (link_info->wrap_hash != NULL)
1048 	{
1049 	  struct elf_link_hash_entry **cur_sym_hashes;
1050 
1051 	  /* Loop only over the symbols whom been already checked.  */
1052 	  for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
1053 	       cur_sym_hashes++)
1054 	    /* If the current symbol is identical to 'sym_hash', that means
1055 	       the symbol was already adjusted (or at least checked).  */
1056 	    if (*cur_sym_hashes == sym_hash)
1057 	      break;
1058 
1059 	  /* Don't adjust the symbol again.  */
1060 	  if (cur_sym_hashes < sym_hashes)
1061 	    continue;
1062 	}
1063 
1064       if ((sym_hash->root.type == bfd_link_hash_defined
1065 	  || sym_hash->root.type == bfd_link_hash_defweak)
1066 	  && sym_hash->root.u.def.section == sec
1067 	  && sym_hash->root.u.def.value == loc)
1068 	return true;
1069     }
1070 
1071   return false;
1072 }
1073 
1074 static bool
ft32_elf_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * link_info,bool * again)1075 ft32_elf_relax_section (bfd *abfd,
1076 			asection *sec,
1077 			struct bfd_link_info *link_info,
1078 			bool *again)
1079 {
1080   Elf_Internal_Rela * free_relocs = NULL;
1081   Elf_Internal_Rela * internal_relocs;
1082   Elf_Internal_Rela * irelend;
1083   Elf_Internal_Rela * irel;
1084   bfd_byte *	      contents = NULL;
1085   Elf_Internal_Shdr * symtab_hdr;
1086   Elf_Internal_Sym *  isymbuf = NULL;
1087 
1088   /* Assume nothing changes.  */
1089   *again = false;
1090 
1091   /* We don't have to do anything for a relocatable link, if
1092      this section does not have relocs, or if this is not a
1093      code section.  */
1094   if (bfd_link_relocatable (link_info)
1095       || sec->reloc_count == 0
1096       || (sec->flags & SEC_RELOC) == 0
1097       || (sec->flags & SEC_HAS_CONTENTS) == 0
1098       || (sec->flags & SEC_CODE) == 0)
1099     return true;
1100 
1101   /* Get the section contents.  */
1102   if (elf_section_data (sec)->this_hdr.contents != NULL)
1103     contents = elf_section_data (sec)->this_hdr.contents;
1104   /* Go get them off disk.  */
1105   else
1106     {
1107       if (! bfd_malloc_and_get_section (abfd, sec, &contents))
1108 	goto error_return;
1109       elf_section_data (sec)->this_hdr.contents = contents;
1110     }
1111 
1112   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1113 
1114   /* Read this BFD's local symbols if we haven't done so already.  */
1115   if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1116     {
1117       isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1118       if (isymbuf == NULL)
1119 	isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1120 					symtab_hdr->sh_info, 0,
1121 					NULL, NULL, NULL);
1122       if (isymbuf == NULL)
1123 	goto error_return;
1124       symtab_hdr->contents = (unsigned char *) isymbuf;
1125     }
1126 
1127   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
1128 					       link_info->keep_memory);
1129   if (internal_relocs == NULL)
1130     goto error_return;
1131   if (! link_info->keep_memory)
1132     free_relocs = internal_relocs;
1133 
1134   /* Walk through them looking for relaxing opportunities.  */
1135   irelend = internal_relocs + sec->reloc_count;
1136 
1137   /* Test every adjacent pair of relocs. If both have shortcodes,
1138      fuse them and delete the relocs.  */
1139   irel = internal_relocs;
1140   while (irel < irelend - 1)
1141     {
1142       Elf_Internal_Rela * irel_next = irel + 1;
1143       unsigned int sc0, sc1;
1144       bfd_vma pc;
1145 
1146       pc = irel->r_offset;
1147 
1148       if (((pc + 4) == (irel_next->r_offset))
1149 	  && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc, irel,
1150 				   &sc0)
1151 	  && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc,
1152 				   irel_next, &sc1)
1153 	  && !elf32_ft32_relax_is_branch_target (link_info, abfd, sec,
1154 						 irel_next->r_offset))
1155 	{
1156 	  unsigned int code30 = (sc1 << 15) | sc0;
1157 	  unsigned int code27 = code30 >> 3;
1158 	  unsigned int code3 = code30 & 7;
1159 	  static const unsigned char pat3[] = {2, 3, 4, 5, 6, 9, 10, 14};
1160 	  unsigned int pattern = pat3[code3];
1161 	  unsigned int fused = (pattern << 27) | code27;
1162 
1163 	  /* Move second reloc to same place as first.  */
1164 	  irel_next->r_offset = irel->r_offset;
1165 
1166 	  /* Change both relocs to R_FT32_NONE.  */
1167 
1168 	  if (ELF32_R_TYPE (irel->r_info) == R_FT32_18)
1169 	    {
1170 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1171 					   R_FT32_SC0);
1172 	    }
1173 	  else
1174 	    {
1175 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1176 					   R_FT32_NONE);
1177 	    }
1178 
1179 	  if (ELF32_R_TYPE (irel_next->r_info) == R_FT32_18)
1180 	    {
1181 	      irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel_next->r_info),
1182 						R_FT32_SC1);
1183 	    }
1184 	  else
1185 	    {
1186 	      irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1187 						R_FT32_NONE);
1188 	    }
1189 
1190 	  /* Replace the first insn with the fused version.  */
1191 	  bfd_put_32 (abfd, fused, contents + irel->r_offset);
1192 
1193 	  /* Delete the second insn.  */
1194 	  if (!elf32_ft32_relax_delete_bytes (link_info, abfd, sec,
1195 					       irel->r_offset + 4, 4))
1196 	    goto error_return;
1197 
1198 	  /* That will change things, so, we should relax again.
1199 	     Note that this is not required, and it may be slow.  */
1200 	  *again = true;
1201 
1202 	  irel += 2;
1203 	}
1204       else
1205 	{
1206 	  irel += 1;
1207 	}
1208     }
1209 
1210   if (isymbuf != NULL
1211       && symtab_hdr->contents != (unsigned char *) isymbuf)
1212     {
1213       if (! link_info->keep_memory)
1214 	free (isymbuf);
1215       else
1216        /* Cache the symbols for elf_link_input_bfd.  */
1217        symtab_hdr->contents = (unsigned char *) isymbuf;
1218     }
1219 
1220   if (contents != NULL
1221       && elf_section_data (sec)->this_hdr.contents != contents)
1222     {
1223       if (! link_info->keep_memory)
1224 	free (contents);
1225       else
1226        /* Cache the section contents for elf_link_input_bfd.  */
1227        elf_section_data (sec)->this_hdr.contents = contents;
1228 
1229     }
1230 
1231   if (elf_section_data (sec)->relocs != internal_relocs)
1232     free (internal_relocs);
1233 
1234   return true;
1235 
1236  error_return:
1237   free (free_relocs);
1238 
1239   return true;
1240 }
1241 
1242 #define ELF_ARCH		bfd_arch_ft32
1243 #define ELF_MACHINE_CODE	EM_FT32
1244 #define ELF_MAXPAGESIZE		0x1
1245 
1246 #define TARGET_LITTLE_SYM       ft32_elf32_vec
1247 #define TARGET_LITTLE_NAME	"elf32-ft32"
1248 
1249 #define elf_info_to_howto_rel			NULL
1250 #define elf_info_to_howto			ft32_info_to_howto_rela
1251 #define elf_backend_relocate_section		ft32_elf_relocate_section
1252 
1253 #define elf_backend_can_gc_sections		1
1254 #define elf_backend_rela_normal			1
1255 
1256 #define bfd_elf32_bfd_reloc_type_lookup		ft32_reloc_type_lookup
1257 #define bfd_elf32_bfd_reloc_name_lookup		ft32_reloc_name_lookup
1258 
1259 #define bfd_elf32_bfd_relax_section		ft32_elf_relax_section
1260 
1261 #include "elf32-target.h"
1262