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