Fix bug in handling R_FR20 relocations.
[external/binutils.git] / bfd / elf32-fr30.c
1 /* FR30-specific support for 32-bit ELF.
2    Copyright (C) 1998 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23 #include "elf-bfd.h"
24 #include "elf/fr30.h"
25
26 /* Forward declarations.  */
27 static bfd_reloc_status_type fr30_elf_i20_reloc
28   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
29 static bfd_reloc_status_type fr30_elf_i32_reloc
30   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
31 static reloc_howto_type * fr30_reloc_type_lookup
32   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
33 static void fr30_info_to_howto_rela 
34   PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
35 static boolean fr30_elf_relocate_section 
36   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
37 static bfd_reloc_status_type fr30_final_link_relocate
38   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
39
40 static reloc_howto_type fr30_elf_howto_table [] =
41 {
42   /* This reloc does nothing.  */
43   HOWTO (R_FR30_NONE,           /* type */
44          0,                     /* rightshift */
45          2,                     /* size (0 = byte, 1 = short, 2 = long) */
46          32,                    /* bitsize */
47          false,                 /* pc_relative */
48          0,                     /* bitpos */
49          complain_overflow_bitfield, /* complain_on_overflow */
50          bfd_elf_generic_reloc, /* special_function */
51          "R_FR30_NONE",         /* name */
52          false,                 /* partial_inplace */
53          0,                     /* src_mask */
54          0,                     /* dst_mask */
55          false),                /* pcrel_offset */
56
57   /* An 8 bit absolute relocation.  */
58   HOWTO (R_FR30_8,              /* type */
59          0,                     /* rightshift */
60          1,                     /* size (0 = byte, 1 = short, 2 = long) */
61          8,                     /* bitsize */
62          false,                 /* pc_relative */
63          4,                     /* bitpos */
64          complain_overflow_bitfield, /* complain_on_overflow */
65          bfd_elf_generic_reloc, /* special_function */
66          "R_FR30_8",            /* name */
67          true,                  /* partial_inplace */
68          0x0000,                /* src_mask */
69          0x0ff0,                /* dst_mask */
70          false),                /* pcrel_offset */
71
72   /* A 20 bit absolute relocation.  */
73   HOWTO (R_FR30_20,             /* type */
74          0,                     /* rightshift */
75          2,                     /* size (0 = byte, 1 = short, 2 = long) */
76          20,                    /* bitsize */
77          false,                 /* pc_relative */
78          0,                     /* bitpos */
79          complain_overflow_bitfield, /* complain_on_overflow */
80          fr30_elf_i20_reloc,    /* special_function */
81          "R_FR30_20",           /* name */
82          true,                  /* partial_inplace */
83          0x00000000,            /* src_mask */
84          0x00f0ffff,            /* dst_mask */
85          false),                /* pcrel_offset */
86
87   /* A 32 bit absolute relocation.  */
88   HOWTO (R_FR30_32,             /* type */
89          0,                     /* rightshift */
90          2,                     /* size (0 = byte, 1 = short, 2 = long) */
91          32,                    /* bitsize */
92          false,                 /* pc_relative */
93          0,                     /* bitpos */
94          complain_overflow_bitfield, /* complain_on_overflow */
95          bfd_elf_generic_reloc, /* special_function */
96          "R_FR30_32",           /* name */
97          true,                  /* partial_inplace */
98          0x00000000,            /* src_mask */
99          0xffffffff,            /* dst_mask */
100          false),                /* pcrel_offset */
101
102   /* A 32 bit into 48 bits absolute relocation.  */
103   HOWTO (R_FR30_48,             /* type */
104          0,                     /* rightshift */
105          2,                     /* size (0 = byte, 1 = short, 2 = long) */
106          32,                    /* bitsize */
107          false,                 /* pc_relative */
108          0,                     /* bitpos */
109          complain_overflow_bitfield, /* complain_on_overflow */
110          fr30_elf_i32_reloc,    /* special_function */
111          "R_FR30_48",           /* name */
112          true,                  /* partial_inplace */
113          0x00000000,            /* src_mask */
114          0xffffffff,            /* dst_mask */
115          false),                /* pcrel_offset */
116
117   /* A 6 bit absolute relocation.  */
118   HOWTO (R_FR30_6_IN_4,         /* type */
119          2,                     /* rightshift */
120          1,                     /* size (0 = byte, 1 = short, 2 = long) */
121          6,                     /* bitsize */
122          false,                 /* pc_relative */
123          4,                     /* bitpos */
124          complain_overflow_unsigned, /* complain_on_overflow */
125          bfd_elf_generic_reloc, /* special_function */
126          "R_FR30_6_IN_4",       /* name */
127          true,                  /* partial_inplace */
128          0x0000,                /* src_mask */
129          0x00f0,                /* dst_mask */
130          false),                /* pcrel_offset */
131   
132   /* An 8 bit absolute relocation.  */
133   HOWTO (R_FR30_8_IN_8,         /* type */
134          0,                     /* rightshift */
135          1,                     /* size (0 = byte, 1 = short, 2 = long) */
136          8,                     /* bitsize */
137          false,                 /* pc_relative */
138          4,                     /* bitpos */
139          complain_overflow_signed, /* complain_on_overflow */
140          bfd_elf_generic_reloc,/* special_function */
141          "R_FR30_8_IN_8",       /* name */
142          true,                  /* partial_inplace */
143          0x0000,                /* src_mask */
144          0x0ff0,                /* dst_mask */
145          false),                /* pcrel_offset */
146   
147   /* A 9 bit absolute relocation.  */
148   HOWTO (R_FR30_9_IN_8,         /* type */
149          1,                     /* rightshift */
150          1,                     /* size (0 = byte, 1 = short, 2 = long) */
151          9,                     /* bitsize */
152          false,                 /* pc_relative */
153          4,                     /* bitpos */
154          complain_overflow_signed, /* complain_on_overflow */
155          bfd_elf_generic_reloc,/* special_function */
156          "R_FR30_9_IN_8",       /* name */
157          true,                  /* partial_inplace */
158          0x0000,                /* src_mask */
159          0x0ff0,                /* dst_mask */
160          false),                /* pcrel_offset */
161   
162   /* A 10 bit absolute relocation.  */
163   HOWTO (R_FR30_10_IN_8,        /* type */
164          2,                     /* rightshift */
165          1,                     /* size (0 = byte, 1 = short, 2 = long) */
166          10,                    /* bitsize */
167          false,                 /* pc_relative */
168          4,                     /* bitpos */
169          complain_overflow_signed, /* complain_on_overflow */
170          bfd_elf_generic_reloc,/* special_function */
171          "R_FR30_10_IN_8",      /* name */
172          true,                  /* partial_inplace */
173          0x0000,                /* src_mask */
174          0x0ff0,                /* dst_mask */
175          false),                /* pcrel_offset */
176
177   /* A PC relative 9 bit relocation, right shifted by 1.  */
178   HOWTO (R_FR30_9_PCREL,        /* type */
179          1,                     /* rightshift */
180          1,                     /* size (0 = byte, 1 = short, 2 = long) */
181          9,                     /* bitsize */
182          true,                  /* pc_relative */
183          0,                     /* bitpos */
184          complain_overflow_signed, /* complain_on_overflow */
185          bfd_elf_generic_reloc, /* special_function */
186          "R_FR30_9_PCREL",      /* name */
187          false,                 /* partial_inplace */
188          0x0000,                /* src_mask */
189          0x00ff,                /* dst_mask */
190          false),                /* pcrel_offset */
191
192   /* A PC relative 12 bit relocation, right shifted by 1.  */
193   HOWTO (R_FR30_12_PCREL,       /* type */
194          1,                     /* rightshift */
195          1,                     /* size (0 = byte, 1 = short, 2 = long) */
196          12,                    /* bitsize */
197          true,                  /* pc_relative */
198          0,                     /* bitpos */
199          complain_overflow_signed, /* complain_on_overflow */
200          bfd_elf_generic_reloc, /* special_function */
201          "R_FR30_12_PCREL",     /* name */
202          false,                 /* partial_inplace */
203          0x0000,                /* src_mask */
204          0x07ff,                /* dst_mask */
205          false),                /* pcrel_offset */
206 };
207 \f
208 /* Utility to actually perform an R_FR30_20 reloc.  */
209
210 static bfd_reloc_status_type
211 fr30_elf_i20_reloc (abfd, reloc_entry, symbol, data,
212                     input_section, output_bfd, error_message)
213      bfd *      abfd;
214      arelent *  reloc_entry;
215      asymbol *  symbol;
216      PTR        data;
217      asection * input_section;
218      bfd *      output_bfd;
219      char **    error_message;
220 {
221   bfd_vma       relocation;
222   unsigned long x;
223   
224   /* This part is from bfd_elf_generic_reloc.  */
225   if (output_bfd != (bfd *) NULL
226       && (symbol->flags & BSF_SECTION_SYM) == 0
227       && (! reloc_entry->howto->partial_inplace
228           || reloc_entry->addend == 0))
229     {
230       reloc_entry->address += input_section->output_offset;
231       return bfd_reloc_ok;
232     }
233
234   if (output_bfd != NULL)
235     /* FIXME: See bfd_perform_relocation.  Is this right?  */
236     return bfd_reloc_ok;
237
238   relocation =
239     symbol->value
240     + symbol->section->output_section->vma
241     + symbol->section->output_offset
242     + reloc_entry->addend;
243
244   if (relocation > ((1U << 20) - 1))
245     return bfd_reloc_overflow;
246
247   x = bfd_get_32 (abfd, data + reloc_entry->address);
248   x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
249   bfd_put_32 (abfd, x, data + reloc_entry->address);
250
251   return bfd_reloc_ok;
252 }
253
254 \f
255 /* Utility to actually perform a R_FR30_48 reloc.  */
256
257 static bfd_reloc_status_type
258 fr30_elf_i32_reloc (abfd, reloc_entry, symbol, data,
259                     input_section, output_bfd, error_message)
260      bfd *      abfd;
261      arelent *  reloc_entry;
262      asymbol *  symbol;
263      PTR        data;
264      asection * input_section;
265      bfd *      output_bfd;
266      char **    error_message;
267 {
268   bfd_vma       relocation;
269
270   /* This part is from bfd_elf_generic_reloc.  */
271   if (output_bfd != (bfd *) NULL
272       && (symbol->flags & BSF_SECTION_SYM) == 0
273       && (! reloc_entry->howto->partial_inplace
274           || reloc_entry->addend == 0))
275     {
276       reloc_entry->address += input_section->output_offset;
277       return bfd_reloc_ok;
278     }
279
280   if (output_bfd != NULL)
281     /* FIXME: See bfd_perform_relocation.  Is this right?  */
282     return bfd_reloc_ok;
283
284   relocation =
285     symbol->value
286     + symbol->section->output_section->vma
287     + symbol->section->output_offset
288     + reloc_entry->addend;
289
290   bfd_put_32 (abfd, relocation, data + reloc_entry->address + 2);
291
292   return bfd_reloc_ok;
293 }
294 \f
295 /* Map BFD reloc types to FR30 ELF reloc types.  */
296
297 struct fr30_reloc_map
298 {
299   unsigned int bfd_reloc_val;
300   unsigned int fr30_reloc_val;
301 };
302
303 static const struct fr30_reloc_map fr30_reloc_map [] =
304 {
305   { BFD_RELOC_NONE,           R_FR30_NONE },
306   { BFD_RELOC_8,              R_FR30_8 },
307   { BFD_RELOC_FR30_20,        R_FR30_20 },
308   { BFD_RELOC_32,             R_FR30_32 },
309   { BFD_RELOC_FR30_48,        R_FR30_48 },
310   { BFD_RELOC_FR30_6_IN_4,    R_FR30_6_IN_4 },
311   { BFD_RELOC_FR30_8_IN_8,    R_FR30_8_IN_8 },
312   { BFD_RELOC_FR30_9_IN_8,    R_FR30_9_IN_8 },
313   { BFD_RELOC_FR30_10_IN_8,   R_FR30_10_IN_8 },
314   { BFD_RELOC_FR30_9_PCREL,   R_FR30_9_PCREL },
315   { BFD_RELOC_FR30_12_PCREL,  R_FR30_12_PCREL },
316 };
317
318 static reloc_howto_type *
319 fr30_reloc_type_lookup (abfd, code)
320      bfd * abfd;
321      bfd_reloc_code_real_type code;
322 {
323   unsigned int i;
324
325   for (i = sizeof (fr30_reloc_map) / sizeof (fr30_reloc_map[0]);
326        --i;)
327     if (fr30_reloc_map [i].bfd_reloc_val == code)
328       return & fr30_elf_howto_table [fr30_reloc_map[i].fr30_reloc_val];
329   
330   return NULL;
331 }
332
333 /* Set the howto pointer for an FR30 ELF reloc.  */
334
335 static void
336 fr30_info_to_howto_rela (abfd, cache_ptr, dst)
337      bfd * abfd;
338      arelent * cache_ptr;
339      Elf32_Internal_Rela * dst;
340 {
341   unsigned int r_type;
342
343   r_type = ELF32_R_TYPE (dst->r_info);
344   BFD_ASSERT (r_type < (unsigned int) R_FR30_max);
345   cache_ptr->howto = & fr30_elf_howto_table [r_type];
346 }
347 \f
348 /* Perform a single relocation.  By default we use the standard BFD
349    routines, but a few relocs, we have to do them ourselves.  */
350
351 static bfd_reloc_status_type
352 fr30_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
353      reloc_howto_type *  howto;
354      bfd *               input_bfd;
355      asection *          input_section;
356      bfd_byte *          contents;
357      Elf_Internal_Rela * rel;
358      bfd_vma             relocation;
359 {
360   bfd_reloc_status_type r = bfd_reloc_ok;
361   bfd_vma               x;
362   bfd_signed_vma        srel;
363   
364   switch (howto->type)
365     {
366     case R_FR30_20:
367       contents   += rel->r_offset;
368       relocation += rel->r_addend;
369
370       if (relocation > ((1 << 20) - 1))
371         return bfd_reloc_overflow;
372       
373       x = bfd_get_32 (input_bfd, contents);
374       x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
375       bfd_put_32 (input_bfd, x, contents);
376       break;
377       
378     case R_FR30_48:
379       contents   += rel->r_offset + 2;
380       relocation += rel->r_addend;
381       bfd_put_32 (input_bfd, relocation, contents);
382       break;
383
384     case R_FR30_9_PCREL:
385       contents   += rel->r_offset + 1;
386       srel = (bfd_signed_vma) relocation;
387       srel += rel->r_addend;
388       srel -= rel->r_offset;
389       srel -= 2;  /* Branch instructions add 2 to the PC... */
390       srel -= (input_section->output_section->vma +
391                      input_section->output_offset);
392       
393       if (srel & 1)
394         return bfd_reloc_outofrange;
395       if (srel > ((1 << 8) - 1) || (srel < - (1 << 8)))
396         return bfd_reloc_overflow;
397
398       bfd_put_8 (input_bfd, srel >> 1, contents);
399       break;
400
401     case R_FR30_12_PCREL:
402       contents   += rel->r_offset;
403       srel = (bfd_signed_vma) relocation;
404       srel += rel->r_addend;
405       srel -= rel->r_offset;
406       srel -= 2; /* Branch instructions add 2 to the PC... */
407       srel -= (input_section->output_section->vma +
408                      input_section->output_offset);
409       
410       if (srel & 1)
411         return bfd_reloc_outofrange;
412       if (srel > ((1 << 11) - 1) || (srel < - (1 << 11)))
413           return bfd_reloc_overflow;
414       
415       x = bfd_get_16 (input_bfd, contents);
416       x = (x & 0xf800) | ((srel >> 1) & 0x7ff);
417       bfd_put_16 (input_bfd, x, contents);
418       break;
419
420     default:
421       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
422                                     contents, rel->r_offset,
423                                     relocation, rel->r_addend);
424     }
425
426   return r;
427 }
428
429 \f
430 /* Relocate an FR30 ELF section.
431    There is some attempt to make this function usable for many architectures,
432    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
433    if only to serve as a learning tool.
434
435    The RELOCATE_SECTION function is called by the new ELF backend linker
436    to handle the relocations for a section.
437
438    The relocs are always passed as Rela structures; if the section
439    actually uses Rel structures, the r_addend field will always be
440    zero.
441
442    This function is responsible for adjusting the section contents as
443    necessary, and (if using Rela relocs and generating a relocateable
444    output file) adjusting the reloc addend as necessary.
445
446    This function does not have to worry about setting the reloc
447    address or the reloc symbol index.
448
449    LOCAL_SYMS is a pointer to the swapped in local symbols.
450
451    LOCAL_SECTIONS is an array giving the section in the input file
452    corresponding to the st_shndx field of each local symbol.
453
454    The global hash table entry for the global symbols can be found
455    via elf_sym_hashes (input_bfd).
456
457    When generating relocateable output, this function must handle
458    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
459    going to be the section symbol corresponding to the output
460    section, which means that the addend must be adjusted
461    accordingly.  */
462
463 static boolean
464 fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section,
465                            contents, relocs, local_syms, local_sections)
466      bfd *                   output_bfd;
467      struct bfd_link_info *  info;
468      bfd *                   input_bfd;
469      asection *              input_section;
470      bfd_byte *              contents;
471      Elf_Internal_Rela *     relocs;
472      Elf_Internal_Sym *      local_syms;
473      asection **             local_sections;
474 {
475   Elf_Internal_Shdr *           symtab_hdr;
476   struct elf_link_hash_entry ** sym_hashes;
477   Elf_Internal_Rela *           rel;
478   Elf_Internal_Rela *           relend;
479
480   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
481   sym_hashes = elf_sym_hashes (input_bfd);
482   relend     = relocs + input_section->reloc_count;
483
484   for (rel = relocs; rel < relend; rel ++)
485     {
486       reloc_howto_type *           howto;
487       unsigned long                r_symndx;
488       Elf_Internal_Sym *           sym;
489       asection *                   sec;
490       struct elf_link_hash_entry * h;
491       bfd_vma                      relocation;
492       bfd_reloc_status_type        r;
493       const char *                 name = NULL;
494
495       r_symndx = ELF32_R_SYM (rel->r_info);
496
497       if (info->relocateable)
498         {
499           /* This is a relocateable link.  We don't have to change
500              anything, unless the reloc is against a section symbol,
501              in which case we have to adjust according to where the
502              section symbol winds up in the output section.  */
503           if (r_symndx < symtab_hdr->sh_info)
504             {
505               sym = local_syms + r_symndx;
506               
507               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
508                 {
509                   sec = local_sections [r_symndx];
510                   rel->r_addend += sec->output_offset + sym->st_value;
511                 }
512             }
513
514           continue;
515         }
516
517       /* This is a final link.  */
518       howto  = fr30_elf_howto_table + ELF32_R_TYPE (rel->r_info);
519       h      = NULL;
520       sym    = NULL;
521       sec    = NULL;
522       
523       if (r_symndx < symtab_hdr->sh_info)
524         {
525           sym = local_syms + r_symndx;
526           sec = local_sections [r_symndx];
527           relocation = (sec->output_section->vma
528                         + sec->output_offset
529                         + sym->st_value);
530           
531           name = bfd_elf_string_from_elf_section
532             (input_bfd, symtab_hdr->sh_link, sym->st_name);
533           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
534 #if 0
535           fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
536                    sec->name, name, sym->st_name,
537                    sec->output_section->vma, sec->output_offset,
538                    sym->st_value, rel->r_addend);
539 #endif
540         }
541       else
542         {
543           h = sym_hashes [r_symndx - symtab_hdr->sh_info];
544           
545           while (h->root.type == bfd_link_hash_indirect
546                  || h->root.type == bfd_link_hash_warning)
547             h = (struct elf_link_hash_entry *) h->root.u.i.link;
548
549           name = h->root.root.string;
550           
551           if (h->root.type == bfd_link_hash_defined
552               || h->root.type == bfd_link_hash_defweak)
553             {
554               sec = h->root.u.def.section;
555               relocation = (h->root.u.def.value
556                             + sec->output_section->vma
557                             + sec->output_offset);
558 #if 0
559               fprintf (stderr,
560                        "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
561                        sec->name, name, h->root.u.def.value,
562                        sec->output_section->vma, sec->output_offset, relocation);
563 #endif
564             }
565           else if (h->root.type == bfd_link_hash_undefweak)
566             {
567 #if 0
568               fprintf (stderr, "undefined: sec: %s, name: %s\n",
569                        sec->name, name);
570 #endif
571               relocation = 0;
572             }
573           else
574             {
575               if (! ((*info->callbacks->undefined_symbol)
576                      (info, h->root.root.string, input_bfd,
577                       input_section, rel->r_offset)))
578                 return false;
579 #if 0
580               fprintf (stderr, "unknown: name: %s\n", name);
581 #endif
582               relocation = 0;
583             }
584         }
585       
586       r = fr30_final_link_relocate (howto, input_bfd, input_section,
587                                      contents, rel, relocation);
588
589       if (r != bfd_reloc_ok)
590         {
591           const char * msg = (const char *) NULL;
592
593           switch (r)
594             {
595             case bfd_reloc_overflow:
596               r = info->callbacks->reloc_overflow
597                 (info, name, howto->name, (bfd_vma) 0,
598                  input_bfd, input_section, rel->r_offset);
599               break;
600               
601             case bfd_reloc_undefined:
602               r = info->callbacks->undefined_symbol
603                 (info, name, input_bfd, input_section, rel->r_offset);
604               break;
605               
606             case bfd_reloc_outofrange:
607               msg = _("internal error: out of range error");
608               break;
609
610             case bfd_reloc_notsupported:
611               msg = _("internal error: unsupported relocation error");
612               break;
613
614             case bfd_reloc_dangerous:
615               msg = _("internal error: dangerous relocation");
616               break;
617
618             default:
619               msg = _("internal error: unknown error");
620               break;
621             }
622
623           if (msg)
624             r = info->callbacks->warning
625               (info, msg, name, input_bfd, input_section, rel->r_offset);
626
627           if (! r)
628             return false;
629         }
630     }
631
632   return true;
633 }
634 \f
635 #define ELF_ARCH                bfd_arch_fr30
636 #define ELF_MACHINE_CODE        EM_CYGNUS_FR30
637 #define ELF_MAXPAGESIZE         0x1000
638
639 #define TARGET_BIG_SYM          bfd_elf32_fr30_vec
640 #define TARGET_BIG_NAME         "elf32-fr30"
641
642 #define elf_info_to_howto_rel                   NULL
643 #define elf_info_to_howto                       fr30_info_to_howto_rela
644 #define elf_backend_relocate_section            fr30_elf_relocate_section
645
646 #define bfd_elf32_bfd_reloc_type_lookup         fr30_reloc_type_lookup
647                                         
648 #include "elf32-target.h"