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