This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / bfd / elf-m10200.c
1 /* Matsushita 10200 specific support for 32-bit ELF
2    Copyright (C) 1996, 1997 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
25 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
26   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
27 static void mn10200_info_to_howto
28   PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
29 static boolean mn10200_elf_relax_delete_bytes
30   PARAMS ((bfd *, asection *, bfd_vma, int));
31 static boolean mn10200_elf_symbol_address_p
32   PARAMS ((bfd *, asection *, Elf32_External_Sym *, bfd_vma));
33
34 /* We have to use RELA instructions since md_apply_fix3 in the assembler
35    does absolutely nothing.  */
36 #define USE_RELA
37
38 enum reloc_type
39 {
40   R_MN10200_NONE = 0,
41   R_MN10200_32,
42   R_MN10200_16,
43   R_MN10200_8,
44   R_MN10200_24,
45   R_MN10200_PCREL8,
46   R_MN10200_PCREL16,
47   R_MN10200_PCREL24,
48   R_MN10200_MAX
49 };
50
51 static reloc_howto_type elf_mn10200_howto_table[] =
52 {
53   /* Dummy relocation.  Does nothing.  */
54   HOWTO (R_MN10200_NONE,
55          0,
56          2,
57          16,
58          false,
59          0,
60          complain_overflow_bitfield,
61          bfd_elf_generic_reloc,
62          "R_MN10200_NONE",
63          false,
64          0,
65          0,
66          false),
67   /* Standard 32 bit reloc.  */
68   HOWTO (R_MN10200_32,
69          0,
70          2,
71          32,
72          false,
73          0,
74          complain_overflow_bitfield,
75          bfd_elf_generic_reloc,
76          "R_MN10200_32",
77          false,
78          0xffffffff,
79          0xffffffff,
80          false),
81   /* Standard 16 bit reloc.  */
82   HOWTO (R_MN10200_16,
83          0,
84          1,
85          16,
86          false,
87          0,
88          complain_overflow_bitfield,
89          bfd_elf_generic_reloc,
90          "R_MN10200_16",
91          false,
92          0xffff,
93          0xffff,
94          false),
95   /* Standard 8 bit reloc.  */
96   HOWTO (R_MN10200_8,
97          0,
98          0,
99          8,
100          false,
101          0,
102          complain_overflow_bitfield,
103          bfd_elf_generic_reloc,
104          "R_MN10200_8",
105          false,
106          0xff,
107          0xff,
108          false),
109   /* Standard 24 bit reloc.  */
110   HOWTO (R_MN10200_24,
111          0,
112          2,
113          24,
114          false,
115          0,
116          complain_overflow_bitfield,
117          bfd_elf_generic_reloc,
118          "R_MN10200_24",
119          false,
120          0xffffff,
121          0xffffff,
122          false),
123   /* Simple 8 pc-relative reloc.  */
124   HOWTO (R_MN10200_PCREL8,
125          0,
126          0,
127          8,
128          true,
129          0,
130          complain_overflow_bitfield,
131          bfd_elf_generic_reloc,
132          "R_MN10200_PCREL8",
133          false,
134          0xff,
135          0xff,
136          true),
137   /* Simple 16 pc-relative reloc.  */
138   HOWTO (R_MN10200_PCREL16,
139          0,
140          1,
141          16,
142          true,
143          0,
144          complain_overflow_bitfield,
145          bfd_elf_generic_reloc,
146          "R_MN10200_PCREL16",
147          false,
148          0xffff,
149          0xffff,
150          true),
151   /* Simple 32bit pc-relative reloc with a 1 byte adjustment
152      to get the pc-relative offset correct.  */
153   HOWTO (R_MN10200_PCREL24,
154          0,
155          2,
156          24,
157          true,
158          0,
159          complain_overflow_bitfield,
160          bfd_elf_generic_reloc,
161          "R_MN10200_PCREL24",
162          false,
163          0xffffff,
164          0xffffff,
165          true),
166 };
167
168 struct mn10200_reloc_map
169 {
170   unsigned char bfd_reloc_val;
171   unsigned char elf_reloc_val;
172 };
173
174 static const struct mn10200_reloc_map mn10200_reloc_map[] =
175 {
176   { BFD_RELOC_NONE, R_MN10200_NONE, },
177   { BFD_RELOC_32, R_MN10200_32, },
178   { BFD_RELOC_16, R_MN10200_16, },
179   { BFD_RELOC_8, R_MN10200_8, },
180   { BFD_RELOC_24, R_MN10200_24, },
181   { BFD_RELOC_8_PCREL, R_MN10200_PCREL8, },
182   { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, },
183   { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, },
184 };
185
186 static reloc_howto_type *
187 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
188      bfd *abfd;
189      bfd_reloc_code_real_type code;
190 {
191   unsigned int i;
192
193   for (i = 0;
194        i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map);
195        i++)
196     {
197       if (mn10200_reloc_map[i].bfd_reloc_val == code)
198         return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val];
199     }
200
201   return NULL;
202 }
203
204 /* Set the howto pointer for an MN10200 ELF reloc.  */
205
206 static void
207 mn10200_info_to_howto (abfd, cache_ptr, dst)
208      bfd *abfd;
209      arelent *cache_ptr;
210      Elf32_Internal_Rela *dst;
211 {
212   unsigned int r_type;
213
214   r_type = ELF32_R_TYPE (dst->r_info);
215   BFD_ASSERT (r_type < (unsigned int) R_MN10200_MAX);
216   cache_ptr->howto = &elf_mn10200_howto_table[r_type];
217 }
218
219 /* Perform a relocation as part of a final link.  */
220 static bfd_reloc_status_type
221 mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
222                                  input_section, contents, offset, value,
223                                  addend, info, sym_sec, is_local)
224      reloc_howto_type *howto;
225      bfd *input_bfd;
226      bfd *output_bfd;
227      asection *input_section;
228      bfd_byte *contents;
229      bfd_vma offset;
230      bfd_vma value;
231      bfd_vma addend;
232      struct bfd_link_info *info;
233      asection *sym_sec;
234      int is_local;
235 {
236   unsigned long r_type = howto->type;
237   bfd_byte *hit_data = contents + offset;
238
239   switch (r_type)
240     {
241
242     case R_MN10200_NONE:
243       return bfd_reloc_ok;
244
245     case R_MN10200_32:
246       value += addend;
247       bfd_put_32 (input_bfd, value, hit_data);
248       return bfd_reloc_ok;
249
250     case R_MN10200_16:
251       value += addend;
252
253       if ((long)value > 0x7fff || (long)value < -0x8000)
254         return bfd_reloc_overflow;
255
256       bfd_put_16 (input_bfd, value, hit_data);
257       return bfd_reloc_ok;
258
259     case R_MN10200_8:
260       value += addend;
261
262       if ((long)value > 0x7fff || (long)value < -0x8000)
263         return bfd_reloc_overflow;
264
265       bfd_put_8 (input_bfd, value, hit_data);
266       return bfd_reloc_ok;
267
268     case R_MN10200_24:
269       value += addend;
270
271       if ((long)value > 0x7fffff || (long)value < -0x800000)
272         return bfd_reloc_overflow;
273
274       value &= 0xffffff;
275       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
276       bfd_put_32 (input_bfd, value, hit_data);
277       return bfd_reloc_ok;
278
279     case R_MN10200_PCREL8:
280       value -= (input_section->output_section->vma
281                 + input_section->output_offset);
282       value -= offset;
283       value += addend;
284
285       if ((long)value > 0xff || (long)value < -0x100)
286         return bfd_reloc_overflow;
287
288       bfd_put_8 (input_bfd, value, hit_data);
289       return bfd_reloc_ok;
290
291     case R_MN10200_PCREL16:
292       value -= (input_section->output_section->vma
293                 + input_section->output_offset);
294       value -= offset;
295       value += addend;
296
297       if ((long)value > 0xffff || (long)value < -0x10000)
298         return bfd_reloc_overflow;
299
300       bfd_put_16 (input_bfd, value, hit_data);
301       return bfd_reloc_ok;
302
303     case R_MN10200_PCREL24:
304       value -= (input_section->output_section->vma
305                 + input_section->output_offset);
306       value -= offset;
307       value += addend;
308
309       if ((long)value > 0xffffff || (long)value < -0x1000000)
310         return bfd_reloc_overflow;
311
312       value &= 0xffffff;
313       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
314       bfd_put_32 (input_bfd, value, hit_data);
315       return bfd_reloc_ok;
316
317     default:
318       return bfd_reloc_notsupported;
319     }
320 }
321
322 \f
323 /* Relocate an MN10200 ELF section.  */
324 static boolean
325 mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
326                               contents, relocs, local_syms, local_sections)
327      bfd *output_bfd;
328      struct bfd_link_info *info;
329      bfd *input_bfd;
330      asection *input_section;
331      bfd_byte *contents;
332      Elf_Internal_Rela *relocs;
333      Elf_Internal_Sym *local_syms;
334      asection **local_sections;
335 {
336   Elf_Internal_Shdr *symtab_hdr;
337   struct elf_link_hash_entry **sym_hashes;
338   Elf_Internal_Rela *rel, *relend;
339
340   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
341   sym_hashes = elf_sym_hashes (input_bfd);
342
343   rel = relocs;
344   relend = relocs + input_section->reloc_count;
345   for (; rel < relend; rel++)
346     {
347       int r_type;
348       reloc_howto_type *howto;
349       unsigned long r_symndx;
350       Elf_Internal_Sym *sym;
351       asection *sec;
352       struct elf_link_hash_entry *h;
353       bfd_vma relocation;
354       bfd_reloc_status_type r;
355
356       r_symndx = ELF32_R_SYM (rel->r_info);
357       r_type = ELF32_R_TYPE (rel->r_info);
358       howto = elf_mn10200_howto_table + r_type;
359
360       if (info->relocateable)
361         {
362           /* This is a relocateable link.  We don't have to change
363              anything, unless the reloc is against a section symbol,
364              in which case we have to adjust according to where the
365              section symbol winds up in the output section.  */
366           if (r_symndx < symtab_hdr->sh_info)
367             {
368               sym = local_syms + r_symndx;
369               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
370                 {
371                   sec = local_sections[r_symndx];
372                   rel->r_addend += sec->output_offset + sym->st_value;
373                 }
374             }
375
376           continue;
377         }
378
379       /* This is a final link.  */
380       h = NULL;
381       sym = NULL;
382       sec = NULL;
383       if (r_symndx < symtab_hdr->sh_info)
384         {
385           sym = local_syms + r_symndx;
386           sec = local_sections[r_symndx];
387           relocation = (sec->output_section->vma
388                         + sec->output_offset
389                         + sym->st_value);
390         }
391       else
392         {
393           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
394           while (h->root.type == bfd_link_hash_indirect
395                  || h->root.type == bfd_link_hash_warning)
396             h = (struct elf_link_hash_entry *) h->root.u.i.link;
397           if (h->root.type == bfd_link_hash_defined
398               || h->root.type == bfd_link_hash_defweak)
399             {
400               sec = h->root.u.def.section;
401               relocation = (h->root.u.def.value
402                             + sec->output_section->vma
403                             + sec->output_offset);
404             }
405           else if (h->root.type == bfd_link_hash_undefweak)
406             relocation = 0;
407           else
408             {
409               if (! ((*info->callbacks->undefined_symbol)
410                      (info, h->root.root.string, input_bfd,
411                       input_section, rel->r_offset)))
412                 return false;
413               relocation = 0;
414             }
415         }
416
417       r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
418                                            input_section,
419                                            contents, rel->r_offset,
420                                            relocation, rel->r_addend,
421                                            info, sec, h == NULL);
422
423       if (r != bfd_reloc_ok)
424         {
425           const char *name;
426           const char *msg = (const char *)0;
427
428           if (h != NULL)
429             name = h->root.root.string;
430           else
431             {
432               name = (bfd_elf_string_from_elf_section
433                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
434               if (name == NULL || *name == '\0')
435                 name = bfd_section_name (input_bfd, sec);
436             }
437
438           switch (r)
439             {
440             case bfd_reloc_overflow:
441               if (! ((*info->callbacks->reloc_overflow)
442                      (info, name, howto->name, (bfd_vma) 0,
443                       input_bfd, input_section, rel->r_offset)))
444                 return false;
445               break;
446
447             case bfd_reloc_undefined:
448               if (! ((*info->callbacks->undefined_symbol)
449                      (info, name, input_bfd, input_section,
450                       rel->r_offset)))
451                 return false;
452               break;
453
454             case bfd_reloc_outofrange:
455               msg = "internal error: out of range error";
456               goto common_error;
457
458             case bfd_reloc_notsupported:
459               msg = "internal error: unsupported relocation error";
460               goto common_error;
461
462             case bfd_reloc_dangerous:
463               msg = "internal error: dangerous error";
464               goto common_error;
465
466             default:
467               msg = "internal error: unknown error";
468               /* fall through */
469
470             common_error:
471               if (!((*info->callbacks->warning)
472                     (info, msg, name, input_bfd, input_section,
473                      rel->r_offset)))
474                 return false;
475               break;
476             }
477         }
478     }
479
480   return true;
481 }
482
483 /* This function handles relaxing for the mn10200.
484
485    There's quite a few relaxing opportunites available on the mn10200:
486
487         * jsr:24 -> jsr:16                                         2 bytes
488
489         * jmp:24 -> jmp:16                                         2 bytes
490         * jmp:16 -> bra:8                                          1 byte
491
492                 * If the previous instruction is a conditional branch
493                 around the jump/bra, we may be able to reverse its condition
494                 and change its target to the jump's target.  The jump/bra
495                 can then be deleted.                               2 bytes
496
497         * mov abs24 -> mov abs16        2 byte savings
498
499         * Most instructions which accept imm24 can relax to imm16  2 bytes
500         - Most instructions which accept imm16 can relax to imm8   1 byte
501
502         * Most instructions which accept d24 can relax to d16      2 bytes
503         - Most instructions which accept d16 can relax to d8       1 byte
504
505         abs24, imm24, d24 all look the same at the reloc level.  It
506         might make the code simpler if we had different relocs for
507         the various relaxable operand types.
508    
509         We don't handle imm16->imm8 or d16->d8 as they're very rare
510         and somewhat more difficult to support.  */
511
512 static boolean 
513 mn10200_elf_relax_section (abfd, sec, link_info, again)
514      bfd *abfd;
515      asection *sec;
516      struct bfd_link_info *link_info;
517      boolean *again;
518 {
519   Elf_Internal_Shdr *symtab_hdr;
520   Elf_Internal_Rela *internal_relocs;
521   Elf_Internal_Rela *free_relocs = NULL;
522   Elf_Internal_Rela *irel, *irelend;
523   bfd_byte *contents = NULL;
524   bfd_byte *free_contents = NULL;
525   Elf32_External_Sym *extsyms = NULL;
526   Elf32_External_Sym *free_extsyms = NULL;
527
528   /* Assume nothing changes.  */
529   *again = false;
530
531   /* We don't have to do anything for a relocateable link, if
532      this section does not have relocs, or if this is not a
533      code section.  */
534   if (link_info->relocateable
535       || (sec->flags & SEC_RELOC) == 0
536       || sec->reloc_count == 0
537       || (sec->flags & SEC_CODE) == 0)
538     return true;
539
540   /* If this is the first time we have been called for this section,
541      initialize the cooked size.  */
542   if (sec->_cooked_size == 0)
543     sec->_cooked_size = sec->_raw_size;
544
545   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
546
547   /* Get a copy of the native relocations.  */
548   internal_relocs = (_bfd_elf32_link_read_relocs
549                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
550                       link_info->keep_memory));
551   if (internal_relocs == NULL)
552     goto error_return;
553   if (! link_info->keep_memory)
554     free_relocs = internal_relocs;
555
556   /* Walk through them looking for relaxing opportunities.  */
557   irelend = internal_relocs + sec->reloc_count;
558   for (irel = internal_relocs; irel < irelend; irel++)
559     {
560       bfd_vma symval;
561
562       /* If this isn't something that can be relaxed, then ignore
563          this reloc.  */
564       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
565           || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
566           || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
567         continue;
568
569       /* Get the section contents if we haven't done so already.  */
570       if (contents == NULL)
571         {
572           /* Get cached copy if it exists.  */
573           if (elf_section_data (sec)->this_hdr.contents != NULL)
574             contents = elf_section_data (sec)->this_hdr.contents;
575           else
576             {
577               /* Go get them off disk.  */
578               contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
579               if (contents == NULL)
580                 goto error_return;
581               free_contents = contents;
582
583               if (! bfd_get_section_contents (abfd, sec, contents,
584                                               (file_ptr) 0, sec->_raw_size))
585                 goto error_return;
586             }
587         }
588
589       /* Read the local symbols if we haven't done so already.  */
590       if (extsyms == NULL)
591         {
592           /* Get cached copy if it exists.  */
593           if (symtab_hdr->contents != NULL)
594             extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
595           else
596             {
597               /* Go get them off disk.  */
598               extsyms = ((Elf32_External_Sym *)
599                          bfd_malloc (symtab_hdr->sh_info
600                                      * sizeof (Elf32_External_Sym)));
601               if (extsyms == NULL)
602                 goto error_return;
603               free_extsyms = extsyms;
604               if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
605                   || (bfd_read (extsyms, sizeof (Elf32_External_Sym),
606                                 symtab_hdr->sh_info, abfd)
607                       != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))))
608                 goto error_return;
609             }
610         }
611
612       /* Get the value of the symbol referred to by the reloc.  */
613       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
614         {
615           Elf_Internal_Sym isym;
616           asection *sym_sec;
617
618           /* A local symbol.  */
619           bfd_elf32_swap_symbol_in (abfd,
620                                     extsyms + ELF32_R_SYM (irel->r_info),
621                                     &isym);
622
623           sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
624           symval = (isym.st_value
625                     + sym_sec->output_section->vma
626                     + sym_sec->output_offset);
627         }
628       else
629         {
630           unsigned long indx;
631           struct elf_link_hash_entry *h;
632
633           /* An external symbol.  */
634           indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
635           h = elf_sym_hashes (abfd)[indx];
636           BFD_ASSERT (h != NULL);
637           if (h->root.type != bfd_link_hash_defined
638               && h->root.type != bfd_link_hash_defweak)
639             {
640               /* This appears to be a reference to an undefined
641                  symbol.  Just ignore it--it will be caught by the
642                  regular reloc processing.  */
643               continue;
644             }
645
646           symval = (h->root.u.def.value
647                     + h->root.u.def.section->output_section->vma
648                     + h->root.u.def.section->output_offset);
649         }
650
651       /* For simplicity of coding, we are going to modify the section
652          contents, the section relocs, and the BFD symbol table.  We
653          must tell the rest of the code not to free up this
654          information.  It would be possible to instead create a table
655          of changes which have to be made, as is done in coff-mips.c;
656          that would be more work, but would require less memory when
657          the linker is run.  */
658
659
660       /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
661          branch/call.  */
662       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
663         {
664           bfd_vma value = symval;
665
666           /* Deal with pc-relative gunk.  */
667           value -= (sec->output_section->vma + sec->output_offset);
668           value -= irel->r_offset;
669           value += irel->r_addend;
670
671           /* See if the value will fit in 16 bits, note the high value is
672              0x7fff + 2 as the target will be two bytes closer if we are
673              able to relax.  */
674           if ((long)value < 0x8001 && (long)value > -0x8000)
675             {
676               unsigned char code;
677
678               /* Get the opcode.  */
679               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
680
681               if (code != 0xe0 && code != 0xe1)
682                 continue;
683
684               /* Note that we've changed the relocs, section contents, etc.  */
685               elf_section_data (sec)->relocs = internal_relocs;
686               free_relocs = NULL;
687
688               elf_section_data (sec)->this_hdr.contents = contents;
689               free_contents = NULL;
690
691               symtab_hdr->contents = (bfd_byte *) extsyms;
692               free_extsyms = NULL;
693
694               /* Fix the opcode.  */
695               if (code == 0xe0)
696                 bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
697               else if (code == 0xe1)
698                 bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
699
700               /* Fix the relocation's type.  */
701               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
702                                            R_MN10200_PCREL16);
703
704               /* The opcode got shorter too, so we have to fix the
705                  addend and offset too!  */
706               irel->r_addend -= 1;
707               irel->r_offset -= 1;
708
709               /* Delete two bytes of data.  */
710               if (!mn10200_elf_relax_delete_bytes (abfd, sec,
711                                                    irel->r_offset + 1, 2))
712                 goto error_return;
713
714               /* That will change things, so, we should relax again.
715                  Note that this is not required, and it may be slow.  */
716               *again = true;
717             }
718         }
719
720       /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
721          branch.  */
722       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
723         {
724           bfd_vma value = symval;
725
726           /* Deal with pc-relative gunk.  */
727           value -= (sec->output_section->vma + sec->output_offset);
728           value -= irel->r_offset;
729           value += irel->r_addend;
730
731           /* See if the value will fit in 8 bits, note the high value is
732              0x7f + 1 as the target will be one bytes closer if we are
733              able to relax.  */
734           if ((long)value < 0x80 && (long)value > -0x80)
735             {
736               unsigned char code;
737
738               /* Get the opcode.  */
739               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
740
741               if (code != 0xfc)
742                 continue;
743
744               /* Note that we've changed the relocs, section contents, etc.  */
745               elf_section_data (sec)->relocs = internal_relocs;
746               free_relocs = NULL;
747
748               elf_section_data (sec)->this_hdr.contents = contents;
749               free_contents = NULL;
750
751               symtab_hdr->contents = (bfd_byte *) extsyms;
752               free_extsyms = NULL;
753
754               /* Fix the opcode.  */
755               bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
756
757               /* Fix the relocation's type.  */
758               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
759                                            R_MN10200_PCREL8);
760
761               /* Delete one byte of data.  */
762               if (!mn10200_elf_relax_delete_bytes (abfd, sec,
763                                                    irel->r_offset + 1, 1))
764                 goto error_return;
765
766               /* That will change things, so, we should relax again.
767                  Note that this is not required, and it may be slow.  */
768               *again = true;
769             }
770         }
771
772       /* Try to eliminate an unconditional 8 bit pc-relative branch
773          which immediately follows a conditional 8 bit pc-relative
774          branch around the unconditional branch.
775
776             original:           new:
777             bCC lab1            bCC' lab2
778             bra lab2
779            lab1:               lab1:
780
781
782          This happens when the bCC can't reach lab2 at assembly time,
783          but due to other relaxations it can reach at link time.  */
784       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
785         {
786           Elf_Internal_Rela *nrel;
787           bfd_vma value = symval;
788           unsigned char code;
789
790           /* Deal with pc-relative gunk.  */
791           value -= (sec->output_section->vma + sec->output_offset);
792           value -= irel->r_offset;
793           value += irel->r_addend;
794
795           /* Do nothing if this reloc is the last byte in the section.  */
796           if (irel->r_offset == sec->_cooked_size)
797             continue;
798
799           /* See if the next instruction is an unconditional pc-relative
800              branch, more often than not this test will fail, so we
801              test it first to speed things up.  */
802           code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
803           if (code != 0xea)
804             continue;
805
806           /* Also make sure the next relocation applies to the next
807              instruction and that it's a pc-relative 8 bit branch.  */
808           nrel = irel + 1;
809           if (nrel == irelend
810               || irel->r_offset + 2 != nrel->r_offset
811               || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
812             continue;
813
814           /* Make sure our destination immediately follows the
815              unconditional branch.  */
816           if (symval != (sec->output_section->vma + sec->output_offset
817                          + irel->r_offset + 3))
818             continue;
819
820           /* Now make sure we are a conditional branch.  This may not
821              be necessary, but why take the chance. 
822
823              Note these checks assume that R_MN10200_PCREL8 relocs
824              only occur on bCC and bCCx insns.  If they occured
825              elsewhere, we'd need to know the start of this insn
826              for this check to be accurate.  */
827           code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
828           if (code != 0xe0 && code != 0xe1 && code != 0xe2
829               && code != 0xe3 && code != 0xe4 && code != 0xe5
830               && code != 0xe6 && code != 0xe7 && code != 0xe8
831               && code != 0xe9 && code != 0xec && code != 0xed
832               && code != 0xee && code != 0xef && code != 0xfc
833               && code != 0xfd && code != 0xfe && code != 0xff)
834             continue;
835
836           /* We also have to be sure there is no symbol/label
837              at the unconditional branch.  */
838           if (mn10200_elf_symbol_address_p (abfd, sec, extsyms,
839                                             irel->r_offset + 1))
840             continue;
841
842           /* Note that we've changed the relocs, section contents, etc.  */
843           elf_section_data (sec)->relocs = internal_relocs;
844           free_relocs = NULL;
845
846           elf_section_data (sec)->this_hdr.contents = contents;
847           free_contents = NULL;
848
849           symtab_hdr->contents = (bfd_byte *) extsyms;
850           free_extsyms = NULL;
851
852           /* Reverse the condition of the first branch.  */
853           switch (code)
854             {
855               case 0xfc:
856                 code = 0xfd;
857                 break;
858               case 0xfd:
859                 code = 0xfc;
860                 break;
861               case 0xfe:
862                 code = 0xff;
863                 break;
864               case 0xff:
865                 code = 0xfe;
866                 break;
867               case 0xe8:
868                 code = 0xe9;
869                 break;
870               case 0xe9:
871                 code = 0xe8;
872                 break;
873               case 0xe0:
874                 code = 0xe2;
875                 break;
876               case 0xe2:
877                 code = 0xe0;
878                 break;
879               case 0xe3:
880                 code = 0xe1;
881                 break;
882               case 0xe1:
883                 code = 0xe3;
884                 break;
885               case 0xe4:
886                 code = 0xe6;
887                 break;
888               case 0xe6:
889                 code = 0xe4;
890                 break;
891               case 0xe7:
892                 code = 0xe5;
893                 break;
894               case 0xe5:
895                 code = 0xe7;
896                 break;
897               case 0xec:
898                 code = 0xed;
899                 break;
900               case 0xed:
901                 code = 0xec;
902                 break;
903               case 0xee:
904                 code = 0xef;
905                 break;
906               case 0xef:
907                 code = 0xee;
908                 break;
909             }
910           bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
911           
912           /* Set the reloc type and symbol for the first branch
913              from the second branch.  */
914           irel->r_info = nrel->r_info;
915
916           /* Make the reloc for the second branch a null reloc.  */
917           nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
918                                        R_MN10200_NONE);
919
920           /* Delete two bytes of data.  */
921           if (!mn10200_elf_relax_delete_bytes (abfd, sec,
922                                                irel->r_offset + 1, 2))
923             goto error_return;
924
925           /* That will change things, so, we should relax again.
926              Note that this is not required, and it may be slow.  */
927           *again = true;
928         }
929
930       /* Try to turn a 24bit immediate, displacement or absolute address
931          into a 16bit immediate, displacement or absolute address.  */
932       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
933         {
934           bfd_vma value = symval;
935
936           /* See if the value will fit in 16 bits. 
937              We allow any 16bit match here.  We prune those we can't
938              handle below.  */
939           if ((long)value < 0x7fff && (long)value > -0x8000)
940             {
941               unsigned char code;
942
943               /* All insns which have 24bit operands are 5 bytes long,
944                  the first byte will always be 0xf4, but we double check
945                  it just in case.  */
946
947               /* Get the first opcode.  */
948               code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
949
950               if (code != 0xf4)
951                 continue;
952
953               /* Get the second opcode.  */
954               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
955
956               switch (code & 0xfc)
957                 {
958                 /* mov imm24,dn -> mov imm16,dn */
959                 case 0x70:
960                   /* Not safe if the high bit is on as relaxing may
961                      move the value out of high mem and thus not fit
962                      in a signed 16bit value.  */
963                   if (value & 0x8000)
964                     continue;
965
966                   /* Note that we've changed the reldection contents, etc.  */
967                   elf_section_data (sec)->relocs = internal_relocs;
968                   free_relocs = NULL;
969
970                   elf_section_data (sec)->this_hdr.contents = contents;
971                   free_contents = NULL;
972
973                   symtab_hdr->contents = (bfd_byte *) extsyms;
974                   free_extsyms = NULL;
975
976                   /* Fix the opcode.  */
977                   bfd_put_8 (abfd, 0xf8 + (code & 0x03),
978                              contents + irel->r_offset - 2);
979
980                   /* Fix the relocation's type.  */
981                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
982                                                R_MN10200_16);
983
984                   /* The opcode got shorter too, so we have to fix the
985                      addend and offset too!  */
986                   irel->r_offset -= 1;
987
988                   /* Delete two bytes of data.  */
989                   if (!mn10200_elf_relax_delete_bytes (abfd, sec,
990                                                        irel->r_offset + 1, 2))
991                     goto error_return;
992
993                   /* That will change things, so, we should relax again.
994                      Note that this is not required, and it may be slow.  */
995                   *again = true;
996                   break;
997
998                 /* mov imm24,an -> mov imm16,an 
999                    cmp imm24,an -> cmp imm16,an
1000                    mov (abs24),dn -> mov (abs16),dn
1001                    mov dn,(abs24) -> mov dn,(abs16)
1002                    movb dn,(abs24) -> movb dn,(abs16)
1003                    movbu (abs24),dn -> movbu (abs16),dn */
1004                 case 0x74:
1005                 case 0x7c:
1006                 case 0xc0:
1007                 case 0x40:
1008                 case 0x44:
1009                 case 0xc8:
1010                   /* Note that we've changed the reldection contents, etc.  */
1011                   elf_section_data (sec)->relocs = internal_relocs;
1012                   free_relocs = NULL;
1013
1014                   elf_section_data (sec)->this_hdr.contents = contents;
1015                   free_contents = NULL;
1016
1017                   symtab_hdr->contents = (bfd_byte *) extsyms;
1018                   free_extsyms = NULL;
1019
1020                   if ((code & 0xfc) == 0x74)
1021                     code = 0xdc + (code & 0x03);
1022                   else if ((code & 0xfc) == 0x7c)
1023                     code = 0xec + (code & 0x03);
1024                   else if ((code & 0xfc) == 0xc0)
1025                     code = 0xc8 + (code & 0x03);
1026                   else if ((code & 0xfc) == 0x40)
1027                     code = 0xc0 + (code & 0x03);
1028                   else if ((code & 0xfc) == 0x44)
1029                     code = 0xc4 + (code & 0x03);
1030                   else if ((code & 0xfc) == 0xc8)
1031                     code = 0xcc + (code & 0x03);
1032
1033                   /* Fix the opcode.  */
1034                   bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
1035
1036                   /* Fix the relocation's type.  */
1037                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1038                                                R_MN10200_16);
1039
1040                   /* The opcode got shorter too, so we have to fix the
1041                      addend and offset too!  */
1042                   irel->r_offset -= 1;
1043
1044                   /* Delete two bytes of data.  */
1045                   if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1046                                                        irel->r_offset + 1, 2))
1047                     goto error_return;
1048
1049                   /* That will change things, so, we should relax again.
1050                      Note that this is not required, and it may be slow.  */
1051                   *again = true;
1052                   break;
1053
1054                 /* cmp imm24,dn -> cmp imm16,dn
1055                    mov (abs24),an -> mov (abs16),an
1056                    mov an,(abs24) -> mov an,(abs16)
1057                    add imm24,dn -> add imm16,dn
1058                    add imm24,an -> add imm16,an
1059                    sub imm24,dn -> sub imm16,dn
1060                    sub imm24,an -> sub imm16,an 
1061                    And all d24->d16 in memory ops.  */
1062                 case 0x78:
1063                 case 0xd0:
1064                 case 0x50:
1065                 case 0x60:
1066                 case 0x64:
1067                 case 0x68:
1068                 case 0x6c:
1069                 case 0x80:
1070                 case 0xf0:
1071                 case 0x00:
1072                 case 0x10:
1073                 case 0xb0:
1074                 case 0x30:
1075                 case 0xa0:
1076                 case 0x20:
1077                 case 0x90:
1078                   /* Not safe if the high bit is on as relaxing may
1079                      move the value out of high mem and thus not fit
1080                      in a signed 16bit value.  */
1081                   if (((code & 0xfc) == 0x78
1082                         || (code & 0xfc) == 0x60
1083                         || (code & 0xfc) == 0x64
1084                         || (code & 0xfc) == 0x68
1085                         || (code & 0xfc) == 0x6c
1086                         || (code & 0xfc) == 0x80
1087                         || (code & 0xfc) == 0xf0
1088                         || (code & 0xfc) == 0x00
1089                         || (code & 0xfc) == 0x10
1090                         || (code & 0xfc) == 0xb0
1091                         || (code & 0xfc) == 0x30
1092                         || (code & 0xfc) == 0xa0
1093                         || (code & 0xfc) == 0x20
1094                         || (code & 0xfc) == 0x90)
1095                        && (value & 0x8000) != 0)
1096                     continue;
1097
1098                   /* Note that we've changed the reldection contents, etc.  */
1099                   elf_section_data (sec)->relocs = internal_relocs;
1100                   free_relocs = NULL;
1101
1102                   elf_section_data (sec)->this_hdr.contents = contents;
1103                   free_contents = NULL;
1104
1105                   symtab_hdr->contents = (bfd_byte *) extsyms;
1106                   free_extsyms = NULL;
1107
1108                   /* Fix the opcode.  */
1109                   bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
1110
1111                   if ((code & 0xfc) == 0x78)
1112                     code = 0x48 + (code & 0x03);
1113                   else if ((code & 0xfc) == 0xd0)
1114                     code = 0x30 + (code & 0x03);
1115                   else if ((code & 0xfc) == 0x50)
1116                     code = 0x20 + (code & 0x03);
1117                   else if ((code & 0xfc) == 0x60)
1118                     code = 0x18 + (code & 0x03);
1119                   else if ((code & 0xfc) == 0x64)
1120                     code = 0x08 + (code & 0x03);
1121                   else if ((code & 0xfc) == 0x68)
1122                     code = 0x1c + (code & 0x03);
1123                   else if ((code & 0xfc) == 0x6c)
1124                     code = 0x0c + (code & 0x03);
1125                   else if ((code & 0xfc) == 0x80)
1126                     code = 0xc0 + (code & 0x07);
1127                   else if ((code & 0xfc) == 0xf0)
1128                     code = 0xb0 + (code & 0x07);
1129                   else if ((code & 0xfc) == 0x00)
1130                     code = 0x80 + (code & 0x07);
1131                   else if ((code & 0xfc) == 0x10)
1132                     code = 0xa0 + (code & 0x07);
1133                   else if ((code & 0xfc) == 0xb0)
1134                     code = 0x70 + (code & 0x07);
1135                   else if ((code & 0xfc) == 0x30)
1136                     code = 0x60 + (code & 0x07);
1137                   else if ((code & 0xfc) == 0xa0)
1138                     code = 0xd0 + (code & 0x07);
1139                   else if ((code & 0xfc) == 0x20)
1140                     code = 0x90 + (code & 0x07);
1141                   else if ((code & 0xfc) == 0x90)
1142                     code = 0x50 + (code & 0x07);
1143
1144                   bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1145
1146                   /* Fix the relocation's type.  */
1147                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1148                                                R_MN10200_16);
1149
1150                   /* Delete one bytes of data.  */
1151                   if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1152                                                        irel->r_offset + 2, 1))
1153                     goto error_return;
1154
1155                   /* That will change things, so, we should relax again.
1156                      Note that this is not required, and it may be slow.  */
1157                   *again = true;
1158                   break;
1159
1160                 /* movb (abs24),dn ->movbu (abs16),dn extxb bn */
1161                 case 0xc4:
1162                   /* Note that we've changed the reldection contents, etc.  */
1163                   elf_section_data (sec)->relocs = internal_relocs;
1164                   free_relocs = NULL;
1165
1166                   elf_section_data (sec)->this_hdr.contents = contents;
1167                   free_contents = NULL;
1168
1169                   symtab_hdr->contents = (bfd_byte *) extsyms;
1170                   free_extsyms = NULL;
1171
1172                   bfd_put_8 (abfd, 0xcc + (code & 0x03),
1173                              contents + irel->r_offset - 2);
1174
1175                   bfd_put_8 (abfd, 0xb8 + (code & 0x03),
1176                              contents + irel->r_offset - 1);
1177
1178                   /* Fix the relocation's type.  */
1179                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1180                                                R_MN10200_16);
1181
1182                   /* The reloc will be applied one byte in front of its
1183                      current location.  */
1184                   irel->r_offset -= 1;
1185
1186                   /* Delete one bytes of data.  */
1187                   if (!mn10200_elf_relax_delete_bytes (abfd, sec,
1188                                                        irel->r_offset + 2, 1))
1189                     goto error_return;
1190
1191                   /* That will change things, so, we should relax again.
1192                      Note that this is not required, and it may be slow.  */
1193                   *again = true;
1194                   break;
1195                 }
1196             }
1197         }
1198     }
1199
1200   if (free_relocs != NULL)
1201     {
1202       free (free_relocs);
1203       free_relocs = NULL;
1204     }
1205
1206   if (free_contents != NULL)
1207     {
1208       if (! link_info->keep_memory)
1209         free (free_contents);
1210       else
1211         {
1212           /* Cache the section contents for elf_link_input_bfd.  */
1213           elf_section_data (sec)->this_hdr.contents = contents;
1214         }
1215       free_contents = NULL;
1216     }
1217
1218   if (free_extsyms != NULL)
1219     {
1220       if (! link_info->keep_memory)
1221         free (free_extsyms);
1222       else
1223         {
1224           /* Cache the symbols for elf_link_input_bfd.  */
1225           symtab_hdr->contents = extsyms;
1226         }
1227       free_extsyms = NULL;
1228     }
1229
1230   return true;
1231
1232  error_return:
1233   if (free_relocs != NULL)
1234     free (free_relocs);
1235   if (free_contents != NULL)
1236     free (free_contents);
1237   if (free_extsyms != NULL)
1238     free (free_extsyms);
1239   return false;
1240 }
1241
1242 /* Delete some bytes from a section while relaxing.  */
1243
1244 static boolean
1245 mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
1246      bfd *abfd;
1247      asection *sec;
1248      bfd_vma addr;
1249      int count;
1250 {
1251   Elf_Internal_Shdr *symtab_hdr;
1252   Elf32_External_Sym *extsyms;
1253   int shndx;
1254   bfd_byte *contents;
1255   Elf_Internal_Rela *irel, *irelend;
1256   Elf_Internal_Rela *irelalign;
1257   bfd_vma toaddr;
1258   Elf32_External_Sym *esym, *esymend;
1259   struct elf_link_hash_entry **sym_hash, **sym_hash_end;
1260
1261   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1262   extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
1263
1264   shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1265
1266   contents = elf_section_data (sec)->this_hdr.contents;
1267
1268   /* The deletion must stop at the next ALIGN reloc for an aligment
1269      power larger than the number of bytes we are deleting.  */
1270
1271   irelalign = NULL;
1272   toaddr = sec->_cooked_size;
1273
1274   irel = elf_section_data (sec)->relocs;
1275   irelend = irel + sec->reloc_count;
1276
1277   /* Actually delete the bytes.  */
1278   memmove (contents + addr, contents + addr + count, toaddr - addr - count);
1279   sec->_cooked_size -= count;
1280
1281   /* Adjust all the relocs.  */
1282   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1283     {
1284       /* Get the new reloc address.  */
1285       if ((irel->r_offset > addr
1286            && irel->r_offset < toaddr))
1287         irel->r_offset -= count;
1288     }
1289
1290   /* Adjust all the symbols.  */
1291   esym = extsyms;
1292   esymend = esym + symtab_hdr->sh_info;
1293   for (; esym < esymend; esym++)
1294     {
1295       Elf_Internal_Sym isym;
1296
1297       bfd_elf32_swap_symbol_in (abfd, esym, &isym);
1298
1299       if (isym.st_shndx == shndx
1300           && isym.st_value > addr
1301           && isym.st_value < toaddr)
1302         {
1303           isym.st_value -= count;
1304           bfd_elf32_swap_symbol_out (abfd, &isym, esym);
1305         }
1306     }
1307
1308   sym_hash = elf_sym_hashes (abfd);
1309   sym_hash_end = (sym_hash
1310                   + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1311                      - symtab_hdr->sh_info));
1312   for (; sym_hash < sym_hash_end; sym_hash++)
1313     {
1314       if (((*sym_hash)->root.type == bfd_link_hash_defined
1315            || (*sym_hash)->root.type == bfd_link_hash_defweak)
1316           && (*sym_hash)->root.u.def.section == sec
1317           && (*sym_hash)->root.u.def.value > addr
1318           && (*sym_hash)->root.u.def.value < toaddr)
1319         {
1320           (*sym_hash)->root.u.def.value -= count;
1321         }
1322     }
1323
1324   return true;
1325 }
1326
1327 /* Return true if a symbol exists at the given address, else return
1328    false.  */
1329 static boolean
1330 mn10200_elf_symbol_address_p (abfd, sec, extsyms, addr)
1331      bfd *abfd;
1332      asection *sec;
1333      Elf32_External_Sym *extsyms;
1334      bfd_vma addr;
1335 {
1336   Elf_Internal_Shdr *symtab_hdr;
1337   int shndx;
1338   Elf32_External_Sym *esym, *esymend;
1339   struct elf_link_hash_entry **sym_hash, **sym_hash_end;
1340
1341   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1342   shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1343
1344   /* Examine all the symbols.  */
1345   esym = extsyms;
1346   esymend = esym + symtab_hdr->sh_info;
1347   for (; esym < esymend; esym++)
1348     {
1349       Elf_Internal_Sym isym;
1350
1351       bfd_elf32_swap_symbol_in (abfd, esym, &isym);
1352
1353       if (isym.st_shndx == shndx
1354           && isym.st_value == addr)
1355         return true;
1356     }
1357
1358   sym_hash = elf_sym_hashes (abfd);
1359   sym_hash_end = (sym_hash
1360                   + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1361                      - symtab_hdr->sh_info));
1362   for (; sym_hash < sym_hash_end; sym_hash++)
1363     {
1364       if (((*sym_hash)->root.type == bfd_link_hash_defined
1365            || (*sym_hash)->root.type == bfd_link_hash_defweak)
1366           && (*sym_hash)->root.u.def.section == sec
1367           && (*sym_hash)->root.u.def.value == addr)
1368         return true;
1369     }
1370   return false;
1371 }
1372
1373 /* This is a version of bfd_generic_get_relocated_section_contents
1374    which uses mn10200_elf_relocate_section.  */
1375
1376 static bfd_byte *
1377 mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
1378                                             data, relocateable, symbols)
1379      bfd *output_bfd;
1380      struct bfd_link_info *link_info;
1381      struct bfd_link_order *link_order;
1382      bfd_byte *data;
1383      boolean relocateable;
1384      asymbol **symbols;
1385 {
1386   Elf_Internal_Shdr *symtab_hdr;
1387   asection *input_section = link_order->u.indirect.section;
1388   bfd *input_bfd = input_section->owner;
1389   asection **sections = NULL;
1390   Elf_Internal_Rela *internal_relocs = NULL;
1391   Elf32_External_Sym *external_syms = NULL;
1392   Elf_Internal_Sym *internal_syms = NULL;
1393
1394   /* We only need to handle the case of relaxing, or of having a
1395      particular set of section contents, specially.  */
1396   if (relocateable
1397       || elf_section_data (input_section)->this_hdr.contents == NULL)
1398     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1399                                                        link_order, data,
1400                                                        relocateable,
1401                                                        symbols);
1402
1403   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1404
1405   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1406           input_section->_raw_size);
1407
1408   if ((input_section->flags & SEC_RELOC) != 0
1409       && input_section->reloc_count > 0)
1410     {
1411       Elf_Internal_Sym *isymp;
1412       asection **secpp;
1413       Elf32_External_Sym *esym, *esymend;
1414
1415       if (symtab_hdr->contents != NULL)
1416         external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
1417       else
1418         {
1419           external_syms = ((Elf32_External_Sym *)
1420                            bfd_malloc (symtab_hdr->sh_info
1421                                        * sizeof (Elf32_External_Sym)));
1422           if (external_syms == NULL && symtab_hdr->sh_info > 0)
1423             goto error_return;
1424           if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
1425               || (bfd_read (external_syms, sizeof (Elf32_External_Sym),
1426                             symtab_hdr->sh_info, input_bfd)
1427                   != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))))
1428             goto error_return;
1429         }
1430
1431       internal_relocs = (_bfd_elf32_link_read_relocs
1432                          (input_bfd, input_section, (PTR) NULL,
1433                           (Elf_Internal_Rela *) NULL, false));
1434       if (internal_relocs == NULL)
1435         goto error_return;
1436
1437       internal_syms = ((Elf_Internal_Sym *)
1438                        bfd_malloc (symtab_hdr->sh_info
1439                                    * sizeof (Elf_Internal_Sym)));
1440       if (internal_syms == NULL && symtab_hdr->sh_info > 0)
1441         goto error_return;
1442
1443       sections = (asection **) bfd_malloc (symtab_hdr->sh_info
1444                                            * sizeof (asection *));
1445       if (sections == NULL && symtab_hdr->sh_info > 0)
1446         goto error_return;
1447
1448       isymp = internal_syms;
1449       secpp = sections;
1450       esym = external_syms;
1451       esymend = esym + symtab_hdr->sh_info;
1452       for (; esym < esymend; ++esym, ++isymp, ++secpp)
1453         {
1454           asection *isec;
1455
1456           bfd_elf32_swap_symbol_in (input_bfd, esym, isymp);
1457
1458           if (isymp->st_shndx == SHN_UNDEF)
1459             isec = bfd_und_section_ptr;
1460           else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
1461             isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
1462           else if (isymp->st_shndx == SHN_ABS)
1463             isec = bfd_abs_section_ptr;
1464           else if (isymp->st_shndx == SHN_COMMON)
1465             isec = bfd_com_section_ptr;
1466           else
1467             {
1468               /* Who knows?  */
1469               isec = NULL;
1470             }
1471
1472           *secpp = isec;
1473         }
1474
1475       if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
1476                                      input_section, data, internal_relocs,
1477                                      internal_syms, sections))
1478         goto error_return;
1479
1480       if (sections != NULL)
1481         free (sections);
1482       sections = NULL;
1483       if (internal_syms != NULL)
1484         free (internal_syms);
1485       internal_syms = NULL;
1486       if (external_syms != NULL && symtab_hdr->contents == NULL)
1487         free (external_syms);
1488       external_syms = NULL;
1489       if (internal_relocs != elf_section_data (input_section)->relocs)
1490         free (internal_relocs);
1491       internal_relocs = NULL;
1492     }
1493
1494   return data;
1495
1496  error_return:
1497   if (internal_relocs != NULL
1498       && internal_relocs != elf_section_data (input_section)->relocs)
1499     free (internal_relocs);
1500   if (external_syms != NULL && symtab_hdr->contents == NULL)
1501     free (external_syms);
1502   if (internal_syms != NULL)
1503     free (internal_syms);
1504   if (sections != NULL)
1505     free (sections);
1506   return NULL;
1507 }
1508
1509
1510 #define TARGET_LITTLE_SYM       bfd_elf32_mn10200_vec
1511 #define TARGET_LITTLE_NAME      "elf32-mn10200"
1512 #define ELF_ARCH                bfd_arch_mn10200
1513 #define ELF_MACHINE_CODE        EM_CYGNUS_MN10200
1514 #define ELF_MAXPAGESIZE         0x1000
1515
1516 #define elf_info_to_howto       mn10200_info_to_howto
1517 #define elf_info_to_howto_rel   0
1518 #define elf_backend_relocate_section mn10200_elf_relocate_section
1519 #define bfd_elf32_bfd_relax_section     mn10200_elf_relax_section
1520 #define bfd_elf32_bfd_get_relocated_section_contents \
1521                                 mn10200_elf_get_relocated_section_contents
1522
1523 #define elf_symbol_leading_char '_'
1524
1525 #include "elf32-target.h"