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