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