Home | History | Annotate | Line # | Download | only in bfd
elf-m10200.c revision 1.1.1.4
      1      1.1  christos /* Matsushita 10200 specific support for 32-bit ELF
      2  1.1.1.4  christos    Copyright (C) 1996-2015 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.1.2  christos static bfd_boolean
     27  1.1.1.2  christos mn10200_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
     28  1.1.1.2  christos static bfd_boolean
     29  1.1.1.2  christos mn10200_elf_symbol_address_p (bfd *, asection *, Elf_Internal_Sym *, bfd_vma);
     30      1.1  christos 
     31  1.1.1.2  christos enum reloc_type
     32  1.1.1.2  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.1.2  christos static reloc_howto_type elf_mn10200_howto_table[] =
     45  1.1.1.2  christos {
     46      1.1  christos   /* Dummy relocation.  Does nothing.  */
     47      1.1  christos   HOWTO (R_MN10200_NONE,
     48      1.1  christos 	 0,
     49      1.1  christos 	 2,
     50      1.1  christos 	 16,
     51      1.1  christos 	 FALSE,
     52      1.1  christos 	 0,
     53      1.1  christos 	 complain_overflow_bitfield,
     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.1.2  christos struct mn10200_reloc_map
    162  1.1.1.2  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.1.2  christos static const struct mn10200_reloc_map mn10200_reloc_map[] =
    168  1.1.1.2  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.1.2  christos bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    181  1.1.1.2  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.1.2  christos mn10200_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
    217  1.1.1.2  christos 		       arelent *cache_ptr,
    218  1.1.1.2  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.1.2  christos mn10200_elf_final_link_relocate (reloc_howto_type *howto,
    231  1.1.1.2  christos 				 bfd *input_bfd,
    232  1.1.1.2  christos 				 bfd *output_bfd ATTRIBUTE_UNUSED,
    233  1.1.1.2  christos 				 asection *input_section,
    234  1.1.1.2  christos 				 bfd_byte *contents,
    235  1.1.1.2  christos 				 bfd_vma offset,
    236  1.1.1.2  christos 				 bfd_vma value,
    237  1.1.1.2  christos 				 bfd_vma addend,
    238  1.1.1.2  christos 				 struct bfd_link_info *info ATTRIBUTE_UNUSED,
    239  1.1.1.2  christos 				 asection *sym_sec ATTRIBUTE_UNUSED,
    240  1.1.1.2  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.1.2  christos static bfd_boolean
    331  1.1.1.2  christos mn10200_elf_relocate_section (bfd *output_bfd,
    332  1.1.1.2  christos 			      struct bfd_link_info *info,
    333  1.1.1.2  christos 			      bfd *input_bfd,
    334  1.1.1.2  christos 			      asection *input_section,
    335  1.1.1.2  christos 			      bfd_byte *contents,
    336  1.1.1.2  christos 			      Elf_Internal_Rela *relocs,
    337  1.1.1.2  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.1.3  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.1.3  christos 				   h, sec, relocation,
    380      1.1  christos 				   unresolved_reloc, warned, ignored);
    381      1.1  christos 	}
    382  1.1.1.2  christos 
    383      1.1  christos       if (sec != NULL && discarded_section (sec))
    384  1.1.1.2  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    385      1.1  christos 					 rel, 1, relend, howto, 0, contents);
    386      1.1  christos 
    387      1.1  christos       if (info->relocatable)
    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.1  christos 	    case bfd_reloc_overflow:
    414      1.1  christos 	      if (! ((*info->callbacks->reloc_overflow)
    415      1.1  christos 		     (info, (h ? &h->root : NULL), name, howto->name,
    416      1.1  christos 		      (bfd_vma) 0, input_bfd, input_section,
    417      1.1  christos 		      rel->r_offset)))
    418      1.1  christos 		return FALSE;
    419      1.1  christos 	      break;
    420      1.1  christos 
    421      1.1  christos 	    case bfd_reloc_undefined:
    422      1.1  christos 	      if (! ((*info->callbacks->undefined_symbol)
    423      1.1  christos 		     (info, name, input_bfd, input_section,
    424      1.1  christos 		      rel->r_offset, TRUE)))
    425      1.1  christos 		return FALSE;
    426      1.1  christos 	      break;
    427      1.1  christos 
    428      1.1  christos 	    case bfd_reloc_outofrange:
    429      1.1  christos 	      msg = _("internal error: out of range error");
    430      1.1  christos 	      goto common_error;
    431      1.1  christos 
    432      1.1  christos 	    case bfd_reloc_notsupported:
    433      1.1  christos 	      msg = _("internal error: unsupported relocation error");
    434      1.1  christos 	      goto common_error;
    435      1.1  christos 
    436      1.1  christos 	    case bfd_reloc_dangerous:
    437      1.1  christos 	      msg = _("internal error: dangerous error");
    438      1.1  christos 	      goto common_error;
    439      1.1  christos 
    440      1.1  christos 	    default:
    441      1.1  christos 	      msg = _("internal error: unknown error");
    442      1.1  christos 	      /* fall through */
    443      1.1  christos 
    444      1.1  christos 	    common_error:
    445      1.1  christos 	      if (!((*info->callbacks->warning)
    446      1.1  christos 		    (info, msg, name, input_bfd, input_section,
    447      1.1  christos 		     rel->r_offset)))
    448      1.1  christos 		return FALSE;
    449      1.1  christos 	      break;
    450      1.1  christos 	    }
    451      1.1  christos 	}
    452      1.1  christos     }
    453      1.1  christos 
    454      1.1  christos   return TRUE;
    455      1.1  christos }
    456  1.1.1.2  christos 
    457  1.1.1.2  christos /* Delete some bytes from a section while relaxing.  */
    458  1.1.1.2  christos 
    459  1.1.1.2  christos static bfd_boolean
    460  1.1.1.2  christos mn10200_elf_relax_delete_bytes (bfd *abfd, asection *sec,
    461  1.1.1.2  christos 				bfd_vma addr, int count)
    462  1.1.1.2  christos {
    463  1.1.1.2  christos   Elf_Internal_Shdr *symtab_hdr;
    464  1.1.1.2  christos   unsigned int sec_shndx;
    465  1.1.1.2  christos   bfd_byte *contents;
    466  1.1.1.2  christos   Elf_Internal_Rela *irel, *irelend;
    467  1.1.1.2  christos   bfd_vma toaddr;
    468  1.1.1.2  christos   Elf_Internal_Sym *isym;
    469  1.1.1.2  christos   Elf_Internal_Sym *isymend;
    470  1.1.1.2  christos   struct elf_link_hash_entry **sym_hashes;
    471  1.1.1.2  christos   struct elf_link_hash_entry **end_hashes;
    472  1.1.1.2  christos   unsigned int symcount;
    473  1.1.1.2  christos 
    474  1.1.1.2  christos   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
    475  1.1.1.2  christos 
    476  1.1.1.2  christos   contents = elf_section_data (sec)->this_hdr.contents;
    477  1.1.1.2  christos 
    478  1.1.1.2  christos   toaddr = sec->size;
    479  1.1.1.2  christos 
    480  1.1.1.2  christos   irel = elf_section_data (sec)->relocs;
    481  1.1.1.2  christos   irelend = irel + sec->reloc_count;
    482  1.1.1.2  christos 
    483  1.1.1.2  christos   /* Actually delete the bytes.  */
    484  1.1.1.2  christos   memmove (contents + addr, contents + addr + count,
    485  1.1.1.2  christos 	   (size_t) (toaddr - addr - count));
    486  1.1.1.2  christos   sec->size -= count;
    487  1.1.1.2  christos 
    488  1.1.1.2  christos   /* Adjust all the relocs.  */
    489  1.1.1.2  christos   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
    490  1.1.1.2  christos     {
    491  1.1.1.2  christos       /* Get the new reloc address.  */
    492  1.1.1.2  christos       if ((irel->r_offset > addr
    493  1.1.1.2  christos 	   && irel->r_offset < toaddr))
    494  1.1.1.2  christos 	irel->r_offset -= count;
    495  1.1.1.2  christos     }
    496  1.1.1.2  christos 
    497  1.1.1.2  christos   /* Adjust the local symbols defined in this section.  */
    498  1.1.1.2  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    499  1.1.1.2  christos   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
    500  1.1.1.2  christos   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
    501  1.1.1.2  christos     {
    502  1.1.1.2  christos       if (isym->st_shndx == sec_shndx
    503  1.1.1.2  christos 	  && isym->st_value > addr
    504  1.1.1.2  christos 	  && isym->st_value < toaddr)
    505  1.1.1.2  christos 	isym->st_value -= count;
    506  1.1.1.2  christos     }
    507  1.1.1.2  christos 
    508  1.1.1.2  christos   /* Now adjust the global symbols defined in this section.  */
    509  1.1.1.2  christos   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
    510  1.1.1.2  christos 	      - symtab_hdr->sh_info);
    511  1.1.1.2  christos   sym_hashes = elf_sym_hashes (abfd);
    512  1.1.1.2  christos   end_hashes = sym_hashes + symcount;
    513  1.1.1.2  christos   for (; sym_hashes < end_hashes; sym_hashes++)
    514  1.1.1.2  christos     {
    515  1.1.1.2  christos       struct elf_link_hash_entry *sym_hash = *sym_hashes;
    516  1.1.1.2  christos       if ((sym_hash->root.type == bfd_link_hash_defined
    517  1.1.1.2  christos 	   || sym_hash->root.type == bfd_link_hash_defweak)
    518  1.1.1.2  christos 	  && sym_hash->root.u.def.section == sec
    519  1.1.1.2  christos 	  && sym_hash->root.u.def.value > addr
    520  1.1.1.2  christos 	  && sym_hash->root.u.def.value < toaddr)
    521  1.1.1.2  christos 	{
    522  1.1.1.2  christos 	  sym_hash->root.u.def.value -= count;
    523  1.1.1.2  christos 	}
    524  1.1.1.2  christos     }
    525  1.1.1.2  christos 
    526  1.1.1.2  christos   return TRUE;
    527  1.1.1.2  christos }
    528      1.1  christos 
    529      1.1  christos /* This function handles relaxing for the mn10200.
    530      1.1  christos 
    531      1.1  christos    There are quite a few relaxing opportunities available on the mn10200:
    532      1.1  christos 
    533      1.1  christos 	* jsr:24 -> jsr:16 					   2 bytes
    534      1.1  christos 
    535      1.1  christos 	* jmp:24 -> jmp:16					   2 bytes
    536      1.1  christos 	* jmp:16 -> bra:8					   1 byte
    537      1.1  christos 
    538      1.1  christos 		* If the previous instruction is a conditional branch
    539      1.1  christos 		around the jump/bra, we may be able to reverse its condition
    540      1.1  christos 		and change its target to the jump's target.  The jump/bra
    541      1.1  christos 		can then be deleted.				   2 bytes
    542      1.1  christos 
    543      1.1  christos 	* mov abs24 -> mov abs16	2 byte savings
    544      1.1  christos 
    545      1.1  christos 	* Most instructions which accept imm24 can relax to imm16  2 bytes
    546      1.1  christos 	- Most instructions which accept imm16 can relax to imm8   1 byte
    547      1.1  christos 
    548      1.1  christos 	* Most instructions which accept d24 can relax to d16	   2 bytes
    549      1.1  christos 	- Most instructions which accept d16 can relax to d8	   1 byte
    550      1.1  christos 
    551      1.1  christos 	abs24, imm24, d24 all look the same at the reloc level.  It
    552      1.1  christos 	might make the code simpler if we had different relocs for
    553      1.1  christos 	the various relaxable operand types.
    554      1.1  christos 
    555      1.1  christos 	We don't handle imm16->imm8 or d16->d8 as they're very rare
    556      1.1  christos 	and somewhat more difficult to support.  */
    557      1.1  christos 
    558  1.1.1.2  christos static bfd_boolean
    559  1.1.1.2  christos mn10200_elf_relax_section (bfd *abfd,
    560  1.1.1.2  christos 			   asection *sec,
    561  1.1.1.2  christos 			   struct bfd_link_info *link_info,
    562      1.1  christos 			   bfd_boolean *again)
    563      1.1  christos {
    564      1.1  christos   Elf_Internal_Shdr *symtab_hdr;
    565      1.1  christos   Elf_Internal_Rela *internal_relocs;
    566      1.1  christos   Elf_Internal_Rela *irel, *irelend;
    567      1.1  christos   bfd_byte *contents = NULL;
    568      1.1  christos   Elf_Internal_Sym *isymbuf = NULL;
    569      1.1  christos 
    570      1.1  christos   /* Assume nothing changes.  */
    571      1.1  christos   *again = FALSE;
    572      1.1  christos 
    573      1.1  christos   /* We don't have to do anything for a relocatable link, if
    574      1.1  christos      this section does not have relocs, or if this is not a
    575      1.1  christos      code section.  */
    576      1.1  christos   if (link_info->relocatable
    577      1.1  christos       || (sec->flags & SEC_RELOC) == 0
    578      1.1  christos       || sec->reloc_count == 0
    579      1.1  christos       || (sec->flags & SEC_CODE) == 0)
    580      1.1  christos     return TRUE;
    581      1.1  christos 
    582      1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    583      1.1  christos 
    584      1.1  christos   /* Get a copy of the native relocations.  */
    585  1.1.1.2  christos   internal_relocs = (_bfd_elf_link_read_relocs
    586      1.1  christos 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
    587      1.1  christos 		      link_info->keep_memory));
    588      1.1  christos   if (internal_relocs == NULL)
    589      1.1  christos     goto error_return;
    590      1.1  christos 
    591      1.1  christos   /* Walk through them looking for relaxing opportunities.  */
    592      1.1  christos   irelend = internal_relocs + sec->reloc_count;
    593      1.1  christos   for (irel = internal_relocs; irel < irelend; irel++)
    594      1.1  christos     {
    595      1.1  christos       bfd_vma symval;
    596      1.1  christos 
    597      1.1  christos       /* If this isn't something that can be relaxed, then ignore
    598      1.1  christos 	 this reloc.  */
    599      1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
    600      1.1  christos 	  || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
    601      1.1  christos 	  || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
    602      1.1  christos 	continue;
    603      1.1  christos 
    604      1.1  christos       /* Get the section contents if we haven't done so already.  */
    605      1.1  christos       if (contents == NULL)
    606      1.1  christos 	{
    607      1.1  christos 	  /* Get cached copy if it exists.  */
    608      1.1  christos 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
    609      1.1  christos 	    contents = elf_section_data (sec)->this_hdr.contents;
    610      1.1  christos 	  else
    611      1.1  christos 	    {
    612      1.1  christos 	      /* Go get them off disk.  */
    613      1.1  christos 	      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
    614      1.1  christos 		goto error_return;
    615      1.1  christos 	    }
    616      1.1  christos 	}
    617      1.1  christos 
    618      1.1  christos       /* Read this BFD's local symbols if we haven't done so already.  */
    619      1.1  christos       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
    620      1.1  christos 	{
    621      1.1  christos 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
    622      1.1  christos 	  if (isymbuf == NULL)
    623      1.1  christos 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
    624      1.1  christos 					    symtab_hdr->sh_info, 0,
    625      1.1  christos 					    NULL, NULL, NULL);
    626      1.1  christos 	  if (isymbuf == NULL)
    627      1.1  christos 	    goto error_return;
    628      1.1  christos 	}
    629      1.1  christos 
    630      1.1  christos       /* Get the value of the symbol referred to by the reloc.  */
    631      1.1  christos       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    632      1.1  christos 	{
    633      1.1  christos 	  /* A local symbol.  */
    634      1.1  christos 	  Elf_Internal_Sym *isym;
    635      1.1  christos 	  asection *sym_sec;
    636      1.1  christos 
    637      1.1  christos 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
    638      1.1  christos 	  if (isym->st_shndx == SHN_UNDEF)
    639      1.1  christos 	    sym_sec = bfd_und_section_ptr;
    640      1.1  christos 	  else if (isym->st_shndx == SHN_ABS)
    641      1.1  christos 	    sym_sec = bfd_abs_section_ptr;
    642      1.1  christos 	  else if (isym->st_shndx == SHN_COMMON)
    643      1.1  christos 	    sym_sec = bfd_com_section_ptr;
    644      1.1  christos 	  else
    645      1.1  christos 	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    646      1.1  christos 	  symval = (isym->st_value
    647      1.1  christos 		    + sym_sec->output_section->vma
    648      1.1  christos 		    + sym_sec->output_offset);
    649      1.1  christos 	}
    650      1.1  christos       else
    651      1.1  christos 	{
    652      1.1  christos 	  unsigned long indx;
    653      1.1  christos 	  struct elf_link_hash_entry *h;
    654      1.1  christos 
    655      1.1  christos 	  /* An external symbol.  */
    656      1.1  christos 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
    657      1.1  christos 	  h = elf_sym_hashes (abfd)[indx];
    658      1.1  christos 	  BFD_ASSERT (h != NULL);
    659      1.1  christos 	  if (h->root.type != bfd_link_hash_defined
    660      1.1  christos 	      && h->root.type != bfd_link_hash_defweak)
    661      1.1  christos 	    {
    662      1.1  christos 	      /* This appears to be a reference to an undefined
    663      1.1  christos                  symbol.  Just ignore it--it will be caught by the
    664      1.1  christos                  regular reloc processing.  */
    665      1.1  christos 	      continue;
    666      1.1  christos 	    }
    667      1.1  christos 
    668      1.1  christos 	  symval = (h->root.u.def.value
    669      1.1  christos 		    + h->root.u.def.section->output_section->vma
    670      1.1  christos 		    + h->root.u.def.section->output_offset);
    671      1.1  christos 	}
    672      1.1  christos 
    673      1.1  christos       /* For simplicity of coding, we are going to modify the section
    674      1.1  christos 	 contents, the section relocs, and the BFD symbol table.  We
    675      1.1  christos 	 must tell the rest of the code not to free up this
    676      1.1  christos 	 information.  It would be possible to instead create a table
    677      1.1  christos 	 of changes which have to be made, as is done in coff-mips.c;
    678      1.1  christos 	 that would be more work, but would require less memory when
    679      1.1  christos 	 the linker is run.  */
    680      1.1  christos 
    681      1.1  christos       /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
    682      1.1  christos 	 branch/call.  */
    683      1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
    684      1.1  christos 	{
    685      1.1  christos 	  bfd_vma value = symval;
    686      1.1  christos 
    687      1.1  christos 	  /* Deal with pc-relative gunk.  */
    688      1.1  christos 	  value -= (sec->output_section->vma + sec->output_offset);
    689      1.1  christos 	  value -= (irel->r_offset + 3);
    690      1.1  christos 	  value += irel->r_addend;
    691      1.1  christos 
    692      1.1  christos 	  /* See if the value will fit in 16 bits, note the high value is
    693      1.1  christos 	     0x7fff + 2 as the target will be two bytes closer if we are
    694      1.1  christos 	     able to relax.  */
    695      1.1  christos 	  if ((long) value < 0x8001 && (long) value > -0x8000)
    696      1.1  christos 	    {
    697      1.1  christos 	      unsigned char code;
    698      1.1  christos 
    699      1.1  christos 	      /* Get the opcode.  */
    700      1.1  christos 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
    701      1.1  christos 
    702      1.1  christos 	      if (code != 0xe0 && code != 0xe1)
    703      1.1  christos 		continue;
    704      1.1  christos 
    705      1.1  christos 	      /* Note that we've changed the relocs, section contents, etc.  */
    706      1.1  christos 	      elf_section_data (sec)->relocs = internal_relocs;
    707      1.1  christos 	      elf_section_data (sec)->this_hdr.contents = contents;
    708      1.1  christos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
    709      1.1  christos 
    710      1.1  christos 	      /* Fix the opcode.  */
    711      1.1  christos 	      if (code == 0xe0)
    712      1.1  christos 		bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
    713      1.1  christos 	      else if (code == 0xe1)
    714      1.1  christos 		bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
    715      1.1  christos 
    716      1.1  christos 	      /* Fix the relocation's type.  */
    717      1.1  christos 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
    718      1.1  christos 					   R_MN10200_PCREL16);
    719      1.1  christos 
    720      1.1  christos 	      /* The opcode got shorter too, so we have to fix the offset.  */
    721      1.1  christos 	      irel->r_offset -= 1;
    722      1.1  christos 
    723      1.1  christos 	      /* Delete two bytes of data.  */
    724      1.1  christos 	      if (!mn10200_elf_relax_delete_bytes (abfd, sec,
    725      1.1  christos 						   irel->r_offset + 1, 2))
    726      1.1  christos 		goto error_return;
    727      1.1  christos 
    728      1.1  christos 	      /* That will change things, so, we should relax again.
    729      1.1  christos 		 Note that this is not required, and it may be slow.  */
    730      1.1  christos 	      *again = TRUE;
    731      1.1  christos 	    }
    732      1.1  christos 	}
    733      1.1  christos 
    734      1.1  christos       /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
    735      1.1  christos 	 branch.  */
    736      1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
    737      1.1  christos 	{
    738      1.1  christos 	  bfd_vma value = symval;
    739      1.1  christos 
    740      1.1  christos 	  /* Deal with pc-relative gunk.  */
    741      1.1  christos 	  value -= (sec->output_section->vma + sec->output_offset);
    742      1.1  christos 	  value -= (irel->r_offset + 2);
    743      1.1  christos 	  value += irel->r_addend;
    744      1.1  christos 
    745      1.1  christos 	  /* See if the value will fit in 8 bits, note the high value is
    746      1.1  christos 	     0x7f + 1 as the target will be one bytes closer if we are
    747      1.1  christos 	     able to relax.  */
    748      1.1  christos 	  if ((long) value < 0x80 && (long) value > -0x80)
    749      1.1  christos 	    {
    750      1.1  christos 	      unsigned char code;
    751      1.1  christos 
    752      1.1  christos 	      /* Get the opcode.  */
    753      1.1  christos 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
    754      1.1  christos 
    755      1.1  christos 	      if (code != 0xfc)
    756      1.1  christos 		continue;
    757      1.1  christos 
    758      1.1  christos 	      /* Note that we've changed the relocs, section contents, etc.  */
    759      1.1  christos 	      elf_section_data (sec)->relocs = internal_relocs;
    760      1.1  christos 	      elf_section_data (sec)->this_hdr.contents = contents;
    761      1.1  christos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
    762      1.1  christos 
    763      1.1  christos 	      /* Fix the opcode.  */
    764      1.1  christos 	      bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
    765      1.1  christos 
    766      1.1  christos 	      /* Fix the relocation's type.  */
    767      1.1  christos 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
    768      1.1  christos 					   R_MN10200_PCREL8);
    769      1.1  christos 
    770      1.1  christos 	      /* Delete one byte of data.  */
    771      1.1  christos 	      if (!mn10200_elf_relax_delete_bytes (abfd, sec,
    772      1.1  christos 						   irel->r_offset + 1, 1))
    773      1.1  christos 		goto error_return;
    774      1.1  christos 
    775      1.1  christos 	      /* That will change things, so, we should relax again.
    776      1.1  christos 		 Note that this is not required, and it may be slow.  */
    777      1.1  christos 	      *again = TRUE;
    778      1.1  christos 	    }
    779      1.1  christos 	}
    780      1.1  christos 
    781      1.1  christos       /* Try to eliminate an unconditional 8 bit pc-relative branch
    782      1.1  christos 	 which immediately follows a conditional 8 bit pc-relative
    783      1.1  christos 	 branch around the unconditional branch.
    784      1.1  christos 
    785      1.1  christos 	    original:		new:
    786      1.1  christos 	    bCC lab1		bCC' lab2
    787      1.1  christos 	    bra lab2
    788      1.1  christos 	   lab1:	       lab1:
    789      1.1  christos 
    790      1.1  christos 	 This happens when the bCC can't reach lab2 at assembly time,
    791      1.1  christos 	 but due to other relaxations it can reach at link time.  */
    792      1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
    793      1.1  christos 	{
    794      1.1  christos 	  Elf_Internal_Rela *nrel;
    795      1.1  christos 	  bfd_vma value = symval;
    796      1.1  christos 	  unsigned char code;
    797      1.1  christos 
    798      1.1  christos 	  /* Deal with pc-relative gunk.  */
    799      1.1  christos 	  value -= (sec->output_section->vma + sec->output_offset);
    800      1.1  christos 	  value -= (irel->r_offset + 1);
    801      1.1  christos 	  value += irel->r_addend;
    802      1.1  christos 
    803      1.1  christos 	  /* Do nothing if this reloc is the last byte in the section.  */
    804      1.1  christos 	  if (irel->r_offset == sec->size)
    805      1.1  christos 	    continue;
    806      1.1  christos 
    807      1.1  christos 	  /* See if the next instruction is an unconditional pc-relative
    808      1.1  christos 	     branch, more often than not this test will fail, so we
    809      1.1  christos 	     test it first to speed things up.  */
    810      1.1  christos 	  code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
    811      1.1  christos 	  if (code != 0xea)
    812      1.1  christos 	    continue;
    813      1.1  christos 
    814      1.1  christos 	  /* Also make sure the next relocation applies to the next
    815      1.1  christos 	     instruction and that it's a pc-relative 8 bit branch.  */
    816      1.1  christos 	  nrel = irel + 1;
    817      1.1  christos 	  if (nrel == irelend
    818      1.1  christos 	      || irel->r_offset + 2 != nrel->r_offset
    819      1.1  christos 	      || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
    820      1.1  christos 	    continue;
    821      1.1  christos 
    822      1.1  christos 	  /* Make sure our destination immediately follows the
    823      1.1  christos 	     unconditional branch.  */
    824      1.1  christos 	  if (symval != (sec->output_section->vma + sec->output_offset
    825      1.1  christos 			 + irel->r_offset + 3))
    826      1.1  christos 	    continue;
    827      1.1  christos 
    828      1.1  christos 	  /* Now make sure we are a conditional branch.  This may not
    829      1.1  christos 	     be necessary, but why take the chance.
    830      1.1  christos 
    831      1.1  christos 	     Note these checks assume that R_MN10200_PCREL8 relocs
    832      1.1  christos 	     only occur on bCC and bCCx insns.  If they occured
    833      1.1  christos 	     elsewhere, we'd need to know the start of this insn
    834      1.1  christos 	     for this check to be accurate.  */
    835      1.1  christos 	  code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
    836      1.1  christos 	  if (code != 0xe0 && code != 0xe1 && code != 0xe2
    837      1.1  christos 	      && code != 0xe3 && code != 0xe4 && code != 0xe5
    838      1.1  christos 	      && code != 0xe6 && code != 0xe7 && code != 0xe8
    839      1.1  christos 	      && code != 0xe9 && code != 0xec && code != 0xed
    840      1.1  christos 	      && code != 0xee && code != 0xef && code != 0xfc
    841      1.1  christos 	      && code != 0xfd && code != 0xfe && code != 0xff)
    842      1.1  christos 	    continue;
    843      1.1  christos 
    844      1.1  christos 	  /* We also have to be sure there is no symbol/label
    845      1.1  christos 	     at the unconditional branch.  */
    846      1.1  christos 	  if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
    847      1.1  christos 					    irel->r_offset + 1))
    848      1.1  christos 	    continue;
    849      1.1  christos 
    850      1.1  christos 	  /* Note that we've changed the relocs, section contents, etc.  */
    851      1.1  christos 	  elf_section_data (sec)->relocs = internal_relocs;
    852      1.1  christos 	  elf_section_data (sec)->this_hdr.contents = contents;
    853      1.1  christos 	  symtab_hdr->contents = (unsigned char *) isymbuf;
    854      1.1  christos 
    855      1.1  christos 	  /* Reverse the condition of the first branch.  */
    856      1.1  christos 	  switch (code)
    857      1.1  christos 	    {
    858      1.1  christos 	    case 0xfc:
    859      1.1  christos 	      code = 0xfd;
    860      1.1  christos 	      break;
    861      1.1  christos 	    case 0xfd:
    862      1.1  christos 	      code = 0xfc;
    863      1.1  christos 	      break;
    864      1.1  christos 	    case 0xfe:
    865      1.1  christos 	      code = 0xff;
    866      1.1  christos 	      break;
    867      1.1  christos 	    case 0xff:
    868      1.1  christos 	      code = 0xfe;
    869      1.1  christos 	      break;
    870      1.1  christos 	    case 0xe8:
    871      1.1  christos 	      code = 0xe9;
    872      1.1  christos 	      break;
    873      1.1  christos 	    case 0xe9:
    874      1.1  christos 	      code = 0xe8;
    875      1.1  christos 	      break;
    876      1.1  christos 	    case 0xe0:
    877      1.1  christos 	      code = 0xe2;
    878      1.1  christos 	      break;
    879      1.1  christos 	    case 0xe2:
    880      1.1  christos 	      code = 0xe0;
    881      1.1  christos 	      break;
    882      1.1  christos 	    case 0xe3:
    883      1.1  christos 	      code = 0xe1;
    884      1.1  christos 	      break;
    885      1.1  christos 	    case 0xe1:
    886      1.1  christos 	      code = 0xe3;
    887      1.1  christos 	      break;
    888      1.1  christos 	    case 0xe4:
    889      1.1  christos 	      code = 0xe6;
    890      1.1  christos 	      break;
    891      1.1  christos 	    case 0xe6:
    892      1.1  christos 	      code = 0xe4;
    893      1.1  christos 	      break;
    894      1.1  christos 	    case 0xe7:
    895      1.1  christos 	      code = 0xe5;
    896      1.1  christos 	      break;
    897      1.1  christos 	    case 0xe5:
    898      1.1  christos 	      code = 0xe7;
    899      1.1  christos 	      break;
    900      1.1  christos 	    case 0xec:
    901      1.1  christos 	      code = 0xed;
    902      1.1  christos 	      break;
    903      1.1  christos 	    case 0xed:
    904      1.1  christos 	      code = 0xec;
    905      1.1  christos 	      break;
    906      1.1  christos 	    case 0xee:
    907      1.1  christos 	      code = 0xef;
    908      1.1  christos 	      break;
    909      1.1  christos 	    case 0xef:
    910      1.1  christos 	      code = 0xee;
    911      1.1  christos 	      break;
    912      1.1  christos 	    }
    913      1.1  christos 	  bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
    914      1.1  christos 
    915      1.1  christos 	  /* Set the reloc type and symbol for the first branch
    916      1.1  christos 	     from the second branch.  */
    917      1.1  christos 	  irel->r_info = nrel->r_info;
    918      1.1  christos 
    919      1.1  christos 	  /* Make the reloc for the second branch a null reloc.  */
    920      1.1  christos 	  nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
    921      1.1  christos 				       R_MN10200_NONE);
    922      1.1  christos 
    923      1.1  christos 	  /* Delete two bytes of data.  */
    924      1.1  christos 	  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
    925      1.1  christos 					       irel->r_offset + 1, 2))
    926      1.1  christos 	    goto error_return;
    927      1.1  christos 
    928      1.1  christos 	  /* That will change things, so, we should relax again.
    929      1.1  christos 	     Note that this is not required, and it may be slow.  */
    930      1.1  christos 	  *again = TRUE;
    931      1.1  christos 	}
    932      1.1  christos 
    933      1.1  christos       /* Try to turn a 24bit immediate, displacement or absolute address
    934      1.1  christos 	 into a 16bit immediate, displacement or absolute address.  */
    935      1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
    936      1.1  christos 	{
    937      1.1  christos 	  bfd_vma value = symval;
    938      1.1  christos 
    939      1.1  christos 	  /* See if the value will fit in 16 bits.
    940      1.1  christos 	     We allow any 16bit match here.  We prune those we can't
    941      1.1  christos 	     handle below.  */
    942      1.1  christos 	  if ((long) value < 0x7fff && (long) value > -0x8000)
    943      1.1  christos 	    {
    944      1.1  christos 	      unsigned char code;
    945      1.1  christos 
    946      1.1  christos 	      /* All insns which have 24bit operands are 5 bytes long,
    947      1.1  christos 		 the first byte will always be 0xf4, but we double check
    948      1.1  christos 		 it just in case.  */
    949      1.1  christos 
    950      1.1  christos 	      /* Get the first opcode.  */
    951      1.1  christos 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
    952      1.1  christos 
    953      1.1  christos 	      if (code != 0xf4)
    954      1.1  christos 		continue;
    955      1.1  christos 
    956      1.1  christos 	      /* Get the second opcode.  */
    957      1.1  christos 	      code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
    958      1.1  christos 
    959      1.1  christos 	      switch (code & 0xfc)
    960      1.1  christos 		{
    961      1.1  christos 		/* mov imm24,dn -> mov imm16,dn */
    962      1.1  christos 		case 0x70:
    963      1.1  christos 		  /* Not safe if the high bit is on as relaxing may
    964      1.1  christos 		     move the value out of high mem and thus not fit
    965      1.1  christos 		     in a signed 16bit value.  */
    966      1.1  christos 		  if (value & 0x8000)
    967      1.1  christos 		    continue;
    968      1.1  christos 
    969      1.1  christos 		  /* Note that we've changed the relocation contents, etc.  */
    970      1.1  christos 		  elf_section_data (sec)->relocs = internal_relocs;
    971      1.1  christos 		  elf_section_data (sec)->this_hdr.contents = contents;
    972      1.1  christos 		  symtab_hdr->contents = (unsigned char *) isymbuf;
    973      1.1  christos 
    974      1.1  christos 		  /* Fix the opcode.  */
    975      1.1  christos 		  bfd_put_8 (abfd, 0xf8 + (code & 0x03),
    976      1.1  christos 			     contents + irel->r_offset - 2);
    977      1.1  christos 
    978      1.1  christos 		  /* Fix the relocation's type.  */
    979      1.1  christos 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
    980      1.1  christos 					       R_MN10200_16);
    981      1.1  christos 
    982      1.1  christos 		  /* The opcode got shorter too, so we have to fix the
    983      1.1  christos 		     offset.  */
    984      1.1  christos 		  irel->r_offset -= 1;
    985      1.1  christos 
    986      1.1  christos 		  /* Delete two bytes of data.  */
    987      1.1  christos 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
    988      1.1  christos 						       irel->r_offset + 1, 2))
    989      1.1  christos 		    goto error_return;
    990      1.1  christos 
    991      1.1  christos 		  /* That will change things, so, we should relax again.
    992      1.1  christos 		     Note that this is not required, and it may be slow.  */
    993      1.1  christos 		  *again = TRUE;
    994      1.1  christos 		  break;
    995      1.1  christos 
    996      1.1  christos 		/* mov imm24,an -> mov imm16,an
    997      1.1  christos 		   cmp imm24,an -> cmp imm16,an
    998      1.1  christos 		   mov (abs24),dn -> mov (abs16),dn
    999      1.1  christos 		   mov dn,(abs24) -> mov dn,(abs16)
   1000      1.1  christos 		   movb dn,(abs24) -> movb dn,(abs16)
   1001      1.1  christos 		   movbu (abs24),dn -> movbu (abs16),dn */
   1002      1.1  christos 		case 0x74:
   1003      1.1  christos 		case 0x7c:
   1004      1.1  christos 		case 0xc0:
   1005      1.1  christos 		case 0x40:
   1006      1.1  christos 		case 0x44:
   1007      1.1  christos 		case 0xc8:
   1008      1.1  christos 		  /* Note that we've changed the relocation contents, etc.  */
   1009      1.1  christos 		  elf_section_data (sec)->relocs = internal_relocs;
   1010      1.1  christos 		  elf_section_data (sec)->this_hdr.contents = contents;
   1011      1.1  christos 		  symtab_hdr->contents = (unsigned char *) isymbuf;
   1012      1.1  christos 
   1013      1.1  christos 		  if ((code & 0xfc) == 0x74)
   1014      1.1  christos 		    code = 0xdc + (code & 0x03);
   1015      1.1  christos 		  else if ((code & 0xfc) == 0x7c)
   1016      1.1  christos 		    code = 0xec + (code & 0x03);
   1017      1.1  christos 		  else if ((code & 0xfc) == 0xc0)
   1018      1.1  christos 		    code = 0xc8 + (code & 0x03);
   1019      1.1  christos 		  else if ((code & 0xfc) == 0x40)
   1020      1.1  christos 		    code = 0xc0 + (code & 0x03);
   1021      1.1  christos 		  else if ((code & 0xfc) == 0x44)
   1022      1.1  christos 		    code = 0xc4 + (code & 0x03);
   1023      1.1  christos 		  else if ((code & 0xfc) == 0xc8)
   1024      1.1  christos 		    code = 0xcc + (code & 0x03);
   1025      1.1  christos 
   1026      1.1  christos 		  /* Fix the opcode.  */
   1027      1.1  christos 		  bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
   1028      1.1  christos 
   1029      1.1  christos 		  /* Fix the relocation's type.  */
   1030      1.1  christos 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1031      1.1  christos 					       R_MN10200_16);
   1032      1.1  christos 
   1033      1.1  christos 		  /* The opcode got shorter too, so we have to fix the
   1034      1.1  christos 		     offset.  */
   1035      1.1  christos 		  irel->r_offset -= 1;
   1036      1.1  christos 
   1037      1.1  christos 		  /* Delete two bytes of data.  */
   1038      1.1  christos 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
   1039      1.1  christos 						       irel->r_offset + 1, 2))
   1040      1.1  christos 		    goto error_return;
   1041      1.1  christos 
   1042      1.1  christos 		  /* That will change things, so, we should relax again.
   1043      1.1  christos 		     Note that this is not required, and it may be slow.  */
   1044      1.1  christos 		  *again = TRUE;
   1045      1.1  christos 		  break;
   1046      1.1  christos 
   1047      1.1  christos 		/* cmp imm24,dn -> cmp imm16,dn
   1048      1.1  christos 		   mov (abs24),an -> mov (abs16),an
   1049      1.1  christos 		   mov an,(abs24) -> mov an,(abs16)
   1050      1.1  christos 		   add imm24,dn -> add imm16,dn
   1051      1.1  christos 		   add imm24,an -> add imm16,an
   1052      1.1  christos 		   sub imm24,dn -> sub imm16,dn
   1053      1.1  christos 		   sub imm24,an -> sub imm16,an
   1054      1.1  christos 		   And all d24->d16 in memory ops.  */
   1055      1.1  christos 		case 0x78:
   1056      1.1  christos 		case 0xd0:
   1057      1.1  christos 		case 0x50:
   1058      1.1  christos 		case 0x60:
   1059      1.1  christos 		case 0x64:
   1060      1.1  christos 		case 0x68:
   1061      1.1  christos 		case 0x6c:
   1062      1.1  christos 		case 0x80:
   1063      1.1  christos 		case 0xf0:
   1064      1.1  christos 		case 0x00:
   1065      1.1  christos 		case 0x10:
   1066      1.1  christos 		case 0xb0:
   1067      1.1  christos 		case 0x30:
   1068      1.1  christos 		case 0xa0:
   1069      1.1  christos 		case 0x20:
   1070      1.1  christos 		case 0x90:
   1071      1.1  christos 		  /* Not safe if the high bit is on as relaxing may
   1072      1.1  christos 		     move the value out of high mem and thus not fit
   1073      1.1  christos 		     in a signed 16bit value.  */
   1074      1.1  christos 		  if (((code & 0xfc) == 0x78
   1075      1.1  christos 		       || (code & 0xfc) == 0x60
   1076      1.1  christos 		       || (code & 0xfc) == 0x64
   1077      1.1  christos 		       || (code & 0xfc) == 0x68
   1078      1.1  christos 		       || (code & 0xfc) == 0x6c
   1079      1.1  christos 		       || (code & 0xfc) == 0x80
   1080      1.1  christos 		       || (code & 0xfc) == 0xf0
   1081      1.1  christos 		       || (code & 0xfc) == 0x00
   1082      1.1  christos 		       || (code & 0xfc) == 0x10
   1083      1.1  christos 		       || (code & 0xfc) == 0xb0
   1084      1.1  christos 		       || (code & 0xfc) == 0x30
   1085      1.1  christos 		       || (code & 0xfc) == 0xa0
   1086      1.1  christos 		       || (code & 0xfc) == 0x20
   1087      1.1  christos 		       || (code & 0xfc) == 0x90)
   1088      1.1  christos 		      && (value & 0x8000) != 0)
   1089      1.1  christos 		    continue;
   1090      1.1  christos 
   1091      1.1  christos 		  /* Note that we've changed the relocation contents, etc.  */
   1092      1.1  christos 		  elf_section_data (sec)->relocs = internal_relocs;
   1093      1.1  christos 		  elf_section_data (sec)->this_hdr.contents = contents;
   1094      1.1  christos 		  symtab_hdr->contents = (unsigned char *) isymbuf;
   1095      1.1  christos 
   1096      1.1  christos 		  /* Fix the opcode.  */
   1097      1.1  christos 		  bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
   1098      1.1  christos 
   1099      1.1  christos 		  if ((code & 0xfc) == 0x78)
   1100      1.1  christos 		    code = 0x48 + (code & 0x03);
   1101      1.1  christos 		  else if ((code & 0xfc) == 0xd0)
   1102      1.1  christos 		    code = 0x30 + (code & 0x03);
   1103      1.1  christos 		  else if ((code & 0xfc) == 0x50)
   1104      1.1  christos 		    code = 0x20 + (code & 0x03);
   1105      1.1  christos 		  else if ((code & 0xfc) == 0x60)
   1106      1.1  christos 		    code = 0x18 + (code & 0x03);
   1107      1.1  christos 		  else if ((code & 0xfc) == 0x64)
   1108      1.1  christos 		    code = 0x08 + (code & 0x03);
   1109      1.1  christos 		  else if ((code & 0xfc) == 0x68)
   1110      1.1  christos 		    code = 0x1c + (code & 0x03);
   1111      1.1  christos 		  else if ((code & 0xfc) == 0x6c)
   1112      1.1  christos 		    code = 0x0c + (code & 0x03);
   1113      1.1  christos 		  else if ((code & 0xfc) == 0x80)
   1114      1.1  christos 		    code = 0xc0 + (code & 0x07);
   1115      1.1  christos 		  else if ((code & 0xfc) == 0xf0)
   1116      1.1  christos 		    code = 0xb0 + (code & 0x07);
   1117      1.1  christos 		  else if ((code & 0xfc) == 0x00)
   1118      1.1  christos 		    code = 0x80 + (code & 0x07);
   1119      1.1  christos 		  else if ((code & 0xfc) == 0x10)
   1120      1.1  christos 		    code = 0xa0 + (code & 0x07);
   1121      1.1  christos 		  else if ((code & 0xfc) == 0xb0)
   1122      1.1  christos 		    code = 0x70 + (code & 0x07);
   1123      1.1  christos 		  else if ((code & 0xfc) == 0x30)
   1124      1.1  christos 		    code = 0x60 + (code & 0x07);
   1125      1.1  christos 		  else if ((code & 0xfc) == 0xa0)
   1126      1.1  christos 		    code = 0xd0 + (code & 0x07);
   1127      1.1  christos 		  else if ((code & 0xfc) == 0x20)
   1128      1.1  christos 		    code = 0x90 + (code & 0x07);
   1129      1.1  christos 		  else if ((code & 0xfc) == 0x90)
   1130      1.1  christos 		    code = 0x50 + (code & 0x07);
   1131      1.1  christos 
   1132      1.1  christos 		  bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
   1133      1.1  christos 
   1134      1.1  christos 		  /* Fix the relocation's type.  */
   1135      1.1  christos 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1136      1.1  christos 					       R_MN10200_16);
   1137      1.1  christos 
   1138      1.1  christos 		  /* Delete one bytes of data.  */
   1139      1.1  christos 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
   1140      1.1  christos 						       irel->r_offset + 2, 1))
   1141      1.1  christos 		    goto error_return;
   1142      1.1  christos 
   1143      1.1  christos 		  /* That will change things, so, we should relax again.
   1144      1.1  christos 		     Note that this is not required, and it may be slow.  */
   1145      1.1  christos 		  *again = TRUE;
   1146      1.1  christos 		  break;
   1147      1.1  christos 
   1148      1.1  christos 		/* movb (abs24),dn ->movbu (abs16),dn extxb bn */
   1149      1.1  christos 		case 0xc4:
   1150      1.1  christos 		  /* Note that we've changed the reldection contents, etc.  */
   1151      1.1  christos 		  elf_section_data (sec)->relocs = internal_relocs;
   1152      1.1  christos 		  elf_section_data (sec)->this_hdr.contents = contents;
   1153      1.1  christos 		  symtab_hdr->contents = (unsigned char *) isymbuf;
   1154      1.1  christos 
   1155      1.1  christos 		  bfd_put_8 (abfd, 0xcc + (code & 0x03),
   1156      1.1  christos 			     contents + irel->r_offset - 2);
   1157      1.1  christos 
   1158      1.1  christos 		  bfd_put_8 (abfd, 0xb8 + (code & 0x03),
   1159      1.1  christos 			     contents + irel->r_offset - 1);
   1160      1.1  christos 
   1161      1.1  christos 		  /* Fix the relocation's type.  */
   1162      1.1  christos 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1163      1.1  christos 					       R_MN10200_16);
   1164      1.1  christos 
   1165      1.1  christos 		  /* The reloc will be applied one byte in front of its
   1166      1.1  christos 		     current location.  */
   1167      1.1  christos 		  irel->r_offset -= 1;
   1168      1.1  christos 
   1169      1.1  christos 		  /* Delete one bytes of data.  */
   1170      1.1  christos 		  if (!mn10200_elf_relax_delete_bytes (abfd, sec,
   1171      1.1  christos 						       irel->r_offset + 2, 1))
   1172      1.1  christos 		    goto error_return;
   1173      1.1  christos 
   1174      1.1  christos 		  /* That will change things, so, we should relax again.
   1175      1.1  christos 		     Note that this is not required, and it may be slow.  */
   1176      1.1  christos 		  *again = TRUE;
   1177      1.1  christos 		  break;
   1178      1.1  christos 		}
   1179      1.1  christos 	    }
   1180      1.1  christos 	}
   1181      1.1  christos     }
   1182      1.1  christos 
   1183      1.1  christos   if (isymbuf != NULL
   1184      1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1185      1.1  christos     {
   1186      1.1  christos       if (! link_info->keep_memory)
   1187      1.1  christos 	free (isymbuf);
   1188      1.1  christos       else
   1189      1.1  christos 	{
   1190      1.1  christos 	  /* Cache the symbols for elf_link_input_bfd.  */
   1191      1.1  christos 	  symtab_hdr->contents = (unsigned char *) isymbuf;
   1192      1.1  christos 	}
   1193      1.1  christos     }
   1194      1.1  christos 
   1195      1.1  christos   if (contents != NULL
   1196      1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
   1197      1.1  christos     {
   1198      1.1  christos       if (! link_info->keep_memory)
   1199      1.1  christos 	free (contents);
   1200      1.1  christos       else
   1201      1.1  christos 	{
   1202      1.1  christos 	  /* Cache the section contents for elf_link_input_bfd.  */
   1203      1.1  christos 	  elf_section_data (sec)->this_hdr.contents = contents;
   1204      1.1  christos 	}
   1205      1.1  christos     }
   1206      1.1  christos 
   1207      1.1  christos   if (internal_relocs != NULL
   1208      1.1  christos       && elf_section_data (sec)->relocs != internal_relocs)
   1209      1.1  christos     free (internal_relocs);
   1210      1.1  christos 
   1211      1.1  christos   return TRUE;
   1212      1.1  christos 
   1213      1.1  christos  error_return:
   1214      1.1  christos   if (isymbuf != NULL
   1215      1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1216      1.1  christos     free (isymbuf);
   1217      1.1  christos   if (contents != NULL
   1218      1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
   1219      1.1  christos     free (contents);
   1220      1.1  christos   if (internal_relocs != NULL
   1221      1.1  christos       && 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.1.2  christos static bfd_boolean
   1230  1.1.1.2  christos mn10200_elf_symbol_address_p (bfd *abfd,
   1231  1.1.1.2  christos 			      asection *sec,
   1232  1.1.1.2  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.1.2  christos static bfd_byte *
   1274  1.1.1.2  christos mn10200_elf_get_relocated_section_contents (bfd *output_bfd,
   1275  1.1.1.2  christos 					    struct bfd_link_info *link_info,
   1276  1.1.1.2  christos 					    struct bfd_link_order *link_order,
   1277  1.1.1.2  christos 					    bfd_byte *data,
   1278  1.1.1.2  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.1.2  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.1  christos 
   1355      1.1  christos       if (sections != NULL)
   1356      1.1  christos 	free (sections);
   1357      1.1  christos       if (isymbuf != NULL
   1358      1.1  christos 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
   1359      1.1  christos 	free (isymbuf);
   1360      1.1  christos       if (elf_section_data (input_section)->relocs != internal_relocs)
   1361      1.1  christos 	free (internal_relocs);
   1362      1.1  christos     }
   1363      1.1  christos 
   1364      1.1  christos   return data;
   1365      1.1  christos 
   1366      1.1  christos  error_return:
   1367      1.1  christos   if (sections != NULL)
   1368      1.1  christos     free (sections);
   1369      1.1  christos   if (isymbuf != NULL
   1370      1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1371      1.1  christos     free (isymbuf);
   1372      1.1  christos   if (internal_relocs != NULL
   1373      1.1  christos       && elf_section_data (input_section)->relocs != internal_relocs)
   1374      1.1  christos     free (internal_relocs);
   1375      1.1  christos   return NULL;
   1376      1.1  christos }
   1377  1.1.1.4  christos 
   1378      1.1  christos #define TARGET_LITTLE_SYM	mn10200_elf32_vec
   1379      1.1  christos #define TARGET_LITTLE_NAME	"elf32-mn10200"
   1380      1.1  christos #define ELF_ARCH		bfd_arch_mn10200
   1381      1.1  christos #define ELF_MACHINE_CODE	EM_MN10200
   1382      1.1  christos #define ELF_MACHINE_ALT1	EM_CYGNUS_MN10200
   1383      1.1  christos #define ELF_MAXPAGESIZE		0x1000
   1384      1.1  christos 
   1385      1.1  christos #define elf_backend_rela_normal 1
   1386      1.1  christos #define elf_info_to_howto	mn10200_info_to_howto
   1387      1.1  christos #define elf_info_to_howto_rel	0
   1388      1.1  christos #define elf_backend_relocate_section mn10200_elf_relocate_section
   1389      1.1  christos #define bfd_elf32_bfd_relax_section	mn10200_elf_relax_section
   1390      1.1  christos #define bfd_elf32_bfd_get_relocated_section_contents \
   1391      1.1  christos 				mn10200_elf_get_relocated_section_contents
   1392      1.1  christos 
   1393      1.1  christos #define elf_symbol_leading_char '_'
   1394      1.1  christos 
   1395                    #include "elf32-target.h"
   1396