Home | History | Annotate | Download | only in bfd
      1 /* BFD back-end for National Semiconductor's CRX ELF
      2    Copyright (C) 2004-2014 Free Software Foundation, Inc.
      3    Written by Tomer Levi, NSC, Israel.
      4 
      5    This file is part of BFD, the Binary File Descriptor library.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 #include "sysdep.h"
     23 #include "bfd.h"
     24 #include "bfdlink.h"
     25 #include "libbfd.h"
     26 #include "elf-bfd.h"
     27 #include "elf/crx.h"
     28 
     29 static reloc_howto_type *elf_crx_reloc_type_lookup
     30   (bfd *, bfd_reloc_code_real_type);
     31 static void elf_crx_info_to_howto
     32   (bfd *, arelent *, Elf_Internal_Rela *);
     33 static bfd_boolean elf32_crx_relax_delete_bytes
     34   (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
     35 static bfd_reloc_status_type crx_elf_final_link_relocate
     36   (reloc_howto_type *, bfd *, bfd *, asection *,
     37    bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
     38    struct bfd_link_info *, asection *, int);
     39 static bfd_boolean elf32_crx_relocate_section
     40   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
     41    Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
     42 static bfd_boolean elf32_crx_relax_section
     43   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
     44 static bfd_byte * elf32_crx_get_relocated_section_contents
     45   (bfd *, struct bfd_link_info *, struct bfd_link_order *,
     46    bfd_byte *, bfd_boolean, asymbol **);
     47 
     48 /* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type.  */
     49 
     50 struct crx_reloc_map
     51 {
     52   bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum.  */
     53   unsigned short crx_reloc_type;	   /* CRX relocation type.  */
     54 };
     55 
     56 static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
     57 {
     58   {BFD_RELOC_NONE,	    R_CRX_NONE},
     59   {BFD_RELOC_CRX_REL4,	    R_CRX_REL4},
     60   {BFD_RELOC_CRX_REL8,	    R_CRX_REL8},
     61   {BFD_RELOC_CRX_REL8_CMP,  R_CRX_REL8_CMP},
     62   {BFD_RELOC_CRX_REL16,	    R_CRX_REL16},
     63   {BFD_RELOC_CRX_REL24,	    R_CRX_REL24},
     64   {BFD_RELOC_CRX_REL32,	    R_CRX_REL32},
     65   {BFD_RELOC_CRX_REGREL12,  R_CRX_REGREL12},
     66   {BFD_RELOC_CRX_REGREL22,  R_CRX_REGREL22},
     67   {BFD_RELOC_CRX_REGREL28,  R_CRX_REGREL28},
     68   {BFD_RELOC_CRX_REGREL32,  R_CRX_REGREL32},
     69   {BFD_RELOC_CRX_ABS16,	    R_CRX_ABS16},
     70   {BFD_RELOC_CRX_ABS32,	    R_CRX_ABS32},
     71   {BFD_RELOC_CRX_NUM8,	    R_CRX_NUM8},
     72   {BFD_RELOC_CRX_NUM16,	    R_CRX_NUM16},
     73   {BFD_RELOC_CRX_NUM32,	    R_CRX_NUM32},
     74   {BFD_RELOC_CRX_IMM16,	    R_CRX_IMM16},
     75   {BFD_RELOC_CRX_IMM32,	    R_CRX_IMM32},
     76   {BFD_RELOC_CRX_SWITCH8,   R_CRX_SWITCH8},
     77   {BFD_RELOC_CRX_SWITCH16,  R_CRX_SWITCH16},
     78   {BFD_RELOC_CRX_SWITCH32,  R_CRX_SWITCH32}
     79 };
     80 
     81 static reloc_howto_type crx_elf_howto_table[] =
     82 {
     83   HOWTO (R_CRX_NONE,		/* type */
     84 	 0,			/* rightshift */
     85 	 2,			/* size */
     86 	 32,			/* bitsize */
     87 	 FALSE,			/* pc_relative */
     88 	 0,			/* bitpos */
     89 	 complain_overflow_dont,/* complain_on_overflow */
     90 	 bfd_elf_generic_reloc,	/* special_function */
     91 	 "R_CRX_NONE",		/* name */
     92 	 FALSE,			/* partial_inplace */
     93 	 0,			/* src_mask */
     94 	 0,			/* dst_mask */
     95 	 FALSE),		/* pcrel_offset */
     96 
     97   HOWTO (R_CRX_REL4,		/* type */
     98 	 1,			/* rightshift */
     99 	 0,			/* size */
    100 	 4,			/* bitsize */
    101 	 TRUE,			/* pc_relative */
    102 	 0,			/* bitpos */
    103 	 complain_overflow_bitfield,/* complain_on_overflow */
    104 	 bfd_elf_generic_reloc,	/* special_function */
    105 	 "R_CRX_REL4",		/* name */
    106 	 FALSE,			/* partial_inplace */
    107 	 0x0,			/* src_mask */
    108 	 0xf,			/* dst_mask */
    109 	 FALSE),		/* pcrel_offset */
    110 
    111   HOWTO (R_CRX_REL8,		/* type */
    112 	 1,			/* rightshift */
    113 	 0,			/* size */
    114 	 8,			/* bitsize */
    115 	 TRUE,			/* pc_relative */
    116 	 0,			/* bitpos */
    117 	 complain_overflow_bitfield,/* complain_on_overflow */
    118 	 bfd_elf_generic_reloc,	/* special_function */
    119 	 "R_CRX_REL8",		/* name */
    120 	 FALSE,			/* partial_inplace */
    121 	 0x0,			/* src_mask */
    122 	 0xff,			/* dst_mask */
    123 	 FALSE),		/* pcrel_offset */
    124 
    125   HOWTO (R_CRX_REL8_CMP,	/* type */
    126 	 1,			/* rightshift */
    127 	 0,			/* size */
    128 	 8,			/* bitsize */
    129 	 TRUE,			/* pc_relative */
    130 	 0,			/* bitpos */
    131 	 complain_overflow_bitfield,/* complain_on_overflow */
    132 	 bfd_elf_generic_reloc,	/* special_function */
    133 	 "R_CRX_REL8_CMP",	/* name */
    134 	 FALSE,			/* partial_inplace */
    135 	 0x0,			/* src_mask */
    136 	 0xff,			/* dst_mask */
    137 	 FALSE),		/* pcrel_offset */
    138 
    139   HOWTO (R_CRX_REL16,		/* type */
    140 	 1,			/* rightshift */
    141 	 1,			/* size */
    142 	 16,			/* bitsize */
    143 	 TRUE,			/* pc_relative */
    144 	 0,			/* bitpos */
    145 	 complain_overflow_bitfield,/* complain_on_overflow */
    146 	 bfd_elf_generic_reloc,	/* special_function */
    147 	 "R_CRX_REL16",		/* name */
    148 	 FALSE,			/* partial_inplace */
    149 	 0x0,			/* src_mask */
    150 	 0xffff,		/* dst_mask */
    151 	 FALSE),		/* pcrel_offset */
    152 
    153   HOWTO (R_CRX_REL24,		/* type */
    154 	 1,			/* rightshift */
    155 	 2,			/* size */
    156 	 24,			/* bitsize */
    157 	 TRUE,			/* pc_relative */
    158 	 0,			/* bitpos */
    159 	 complain_overflow_bitfield,/* complain_on_overflow */
    160 	 bfd_elf_generic_reloc,	/* special_function */
    161 	 "R_CRX_REL24",		/* name */
    162 	 FALSE,			/* partial_inplace */
    163 	 0x0,			/* src_mask */
    164 	 0xffffff,		/* dst_mask */
    165 	 FALSE),		/* pcrel_offset */
    166 
    167   HOWTO (R_CRX_REL32,		/* type */
    168 	 1,			/* rightshift */
    169 	 2,			/* size */
    170 	 32,			/* bitsize */
    171 	 TRUE,			/* pc_relative */
    172 	 0,			/* bitpos */
    173 	 complain_overflow_bitfield,/* complain_on_overflow */
    174 	 bfd_elf_generic_reloc,	/* special_function */
    175 	 "R_CRX_REL32",		/* name */
    176 	 FALSE,			/* partial_inplace */
    177 	 0x0,			/* src_mask */
    178 	 0xffffffff,		/* dst_mask */
    179 	 FALSE),		/* pcrel_offset */
    180 
    181   HOWTO (R_CRX_REGREL12,	/* type */
    182 	 0,			/* rightshift */
    183 	 1,			/* size */
    184 	 12,			/* bitsize */
    185 	 FALSE,			/* pc_relative */
    186 	 0,			/* bitpos */
    187 	 complain_overflow_bitfield,/* complain_on_overflow */
    188 	 bfd_elf_generic_reloc,	/* special_function */
    189 	 "R_CRX_REGREL12",	/* name */
    190 	 FALSE,			/* partial_inplace */
    191 	 0x0,			/* src_mask */
    192 	 0xfff,			/* dst_mask */
    193 	 FALSE),		/* pcrel_offset */
    194 
    195   HOWTO (R_CRX_REGREL22,	/* type */
    196 	 0,			/* rightshift */
    197 	 2,			/* size */
    198 	 22,			/* bitsize */
    199 	 FALSE,			/* pc_relative */
    200 	 0,			/* bitpos */
    201 	 complain_overflow_bitfield,/* complain_on_overflow */
    202 	 bfd_elf_generic_reloc,	/* special_function */
    203 	 "R_CRX_REGREL22",	/* name */
    204 	 FALSE,			/* partial_inplace */
    205 	 0x0,			/* src_mask */
    206 	 0x3fffff,		/* dst_mask */
    207 	 FALSE),		/* pcrel_offset */
    208 
    209   HOWTO (R_CRX_REGREL28,	/* type */
    210 	 0,			/* rightshift */
    211 	 2,			/* size */
    212 	 28,			/* bitsize */
    213 	 FALSE,			/* pc_relative */
    214 	 0,			/* bitpos */
    215 	 complain_overflow_bitfield,/* complain_on_overflow */
    216 	 bfd_elf_generic_reloc,	/* special_function */
    217 	 "R_CRX_REGREL28",	/* name */
    218 	 FALSE,			/* partial_inplace */
    219 	 0x0,			/* src_mask */
    220 	 0xfffffff,		/* dst_mask */
    221 	 FALSE),		/* pcrel_offset */
    222 
    223   HOWTO (R_CRX_REGREL32,	/* type */
    224 	 0,			/* rightshift */
    225 	 2,			/* size */
    226 	 32,			/* bitsize */
    227 	 FALSE,			/* pc_relative */
    228 	 0,			/* bitpos */
    229 	 complain_overflow_bitfield,/* complain_on_overflow */
    230 	 bfd_elf_generic_reloc,	/* special_function */
    231 	 "R_CRX_REGREL32",	/* name */
    232 	 FALSE,			/* partial_inplace */
    233 	 0x0,			/* src_mask */
    234 	 0xffffffff,		/* dst_mask */
    235 	 FALSE),		/* pcrel_offset */
    236 
    237   HOWTO (R_CRX_ABS16,		/* type */
    238 	 0,			/* rightshift */
    239 	 1,			/* size */
    240 	 16,			/* bitsize */
    241 	 FALSE,			/* pc_relative */
    242 	 0,			/* bitpos */
    243 	 complain_overflow_bitfield,/* complain_on_overflow */
    244 	 bfd_elf_generic_reloc,	/* special_function */
    245 	 "R_CRX_ABS16",		/* name */
    246 	 FALSE,			/* partial_inplace */
    247 	 0x0,			/* src_mask */
    248 	 0xffff,		/* dst_mask */
    249 	 FALSE),		/* pcrel_offset */
    250 
    251   HOWTO (R_CRX_ABS32,		/* type */
    252 	 0,			/* rightshift */
    253 	 2,			/* size */
    254 	 32,			/* bitsize */
    255 	 FALSE,			/* pc_relative */
    256 	 0,			/* bitpos */
    257 	 complain_overflow_bitfield,/* complain_on_overflow */
    258 	 bfd_elf_generic_reloc,	/* special_function */
    259 	 "R_CRX_ABS32",		/* name */
    260 	 FALSE,			/* partial_inplace */
    261 	 0x0,			/* src_mask */
    262 	 0xffffffff,		/* dst_mask */
    263 	 FALSE),		/* pcrel_offset */
    264 
    265   HOWTO (R_CRX_NUM8,		/* type */
    266 	 0,			/* rightshift */
    267 	 0,			/* size */
    268 	 8,			/* bitsize */
    269 	 FALSE,			/* pc_relative */
    270 	 0,			/* bitpos */
    271 	 complain_overflow_bitfield,/* complain_on_overflow */
    272 	 bfd_elf_generic_reloc,	/* special_function */
    273 	 "R_CRX_NUM8",		/* name */
    274 	 FALSE,			/* partial_inplace */
    275 	 0x0,	  		/* src_mask */
    276 	 0xff,			/* dst_mask */
    277 	 FALSE),		/* pcrel_offset */
    278 
    279   HOWTO (R_CRX_NUM16,		/* type */
    280 	 0,			/* rightshift */
    281 	 1,			/* size */
    282 	 16,			/* bitsize */
    283 	 FALSE,			/* pc_relative */
    284 	 0,			/* bitpos */
    285 	 complain_overflow_bitfield,/* complain_on_overflow */
    286 	 bfd_elf_generic_reloc,	/* special_function */
    287 	 "R_CRX_NUM16",		/* name */
    288 	 FALSE,			/* partial_inplace */
    289 	 0x0,	  		/* src_mask */
    290 	 0xffff,		/* dst_mask */
    291 	 FALSE),		/* pcrel_offset */
    292 
    293   HOWTO (R_CRX_NUM32,		/* type */
    294 	 0,			/* rightshift */
    295 	 2,			/* size */
    296 	 32,			/* bitsize */
    297 	 FALSE,			/* pc_relative */
    298 	 0,			/* bitpos */
    299 	 complain_overflow_bitfield,/* complain_on_overflow */
    300 	 bfd_elf_generic_reloc,	/* special_function */
    301 	 "R_CRX_NUM32",		/* name */
    302 	 FALSE,			/* partial_inplace */
    303 	 0x0,	  		/* src_mask */
    304 	 0xffffffff,		/* dst_mask */
    305 	 FALSE),		/* pcrel_offset */
    306 
    307   HOWTO (R_CRX_IMM16,		/* type */
    308 	 0,			/* rightshift */
    309 	 1,			/* size */
    310 	 16,			/* bitsize */
    311 	 FALSE,			/* pc_relative */
    312 	 0,			/* bitpos */
    313 	 complain_overflow_bitfield,/* complain_on_overflow */
    314 	 bfd_elf_generic_reloc,	/* special_function */
    315 	 "R_CRX_IMM16",		/* name */
    316 	 FALSE,			/* partial_inplace */
    317 	 0x0, 	 		/* src_mask */
    318 	 0xffff,		/* dst_mask */
    319 	 FALSE),		/* pcrel_offset */
    320 
    321   HOWTO (R_CRX_IMM32,		/* type */
    322 	 0,			/* rightshift */
    323 	 2,			/* size */
    324 	 32,			/* bitsize */
    325 	 FALSE,			/* pc_relative */
    326 	 0,			/* bitpos */
    327 	 complain_overflow_bitfield,/* complain_on_overflow */
    328 	 bfd_elf_generic_reloc,	/* special_function */
    329 	 "R_CRX_IMM32",		/* name */
    330 	 FALSE,			/* partial_inplace */
    331 	 0x0,  			/* src_mask */
    332 	 0xffffffff,		/* dst_mask */
    333 	 FALSE),		/* pcrel_offset */
    334 
    335   /* An 8 bit switch table entry.  This is generated for an expression
    336      such as ``.byte L1 - L2''.  The offset holds the difference
    337      between the reloc address and L2.  */
    338   HOWTO (R_CRX_SWITCH8,		/* type */
    339 	 0,			/* rightshift */
    340 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
    341 	 8,			/* bitsize */
    342 	 FALSE,			/* pc_relative */
    343 	 0,			/* bitpos */
    344 	 complain_overflow_unsigned, /* complain_on_overflow */
    345 	 bfd_elf_generic_reloc,	/* special_function */
    346 	 "R_CRX_SWITCH8",	/* name */
    347 	 FALSE,			/* partial_inplace */
    348 	 0x0,			/* src_mask */
    349 	 0xff,			/* dst_mask */
    350 	 TRUE),			/* pcrel_offset */
    351 
    352   /* A 16 bit switch table entry.  This is generated for an expression
    353      such as ``.word L1 - L2''.  The offset holds the difference
    354      between the reloc address and L2.  */
    355   HOWTO (R_CRX_SWITCH16,	/* type */
    356 	 0,			/* rightshift */
    357 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
    358 	 16,			/* bitsize */
    359 	 FALSE,			/* pc_relative */
    360 	 0,			/* bitpos */
    361 	 complain_overflow_unsigned, /* complain_on_overflow */
    362 	 bfd_elf_generic_reloc,	/* special_function */
    363 	 "R_CRX_SWITCH16",	/* name */
    364 	 FALSE,			/* partial_inplace */
    365 	 0x0,			/* src_mask */
    366 	 0xffff,		/* dst_mask */
    367 	 TRUE),			/* pcrel_offset */
    368 
    369   /* A 32 bit switch table entry.  This is generated for an expression
    370      such as ``.long L1 - L2''.  The offset holds the difference
    371      between the reloc address and L2.  */
    372   HOWTO (R_CRX_SWITCH32,	/* type */
    373 	 0,			/* rightshift */
    374 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    375 	 32,			/* bitsize */
    376 	 FALSE,			/* pc_relative */
    377 	 0,			/* bitpos */
    378 	 complain_overflow_unsigned, /* complain_on_overflow */
    379 	 bfd_elf_generic_reloc,	/* special_function */
    380 	 "R_CRX_SWITCH32",	/* name */
    381 	 FALSE,			/* partial_inplace */
    382 	 0x0,			/* src_mask */
    383 	 0xffffffff,		/* dst_mask */
    384 	 TRUE)			/* pcrel_offset */
    385 };
    386 
    387 /* Retrieve a howto ptr using a BFD reloc_code.  */
    388 
    389 static reloc_howto_type *
    390 elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    391 			   bfd_reloc_code_real_type code)
    392 {
    393   unsigned int i;
    394 
    395   for (i = 0; i < R_CRX_MAX; i++)
    396     if (code == crx_reloc_map[i].bfd_reloc_enum)
    397       return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
    398 
    399   printf ("This relocation Type is not supported -0x%x\n", code);
    400   return 0;
    401 }
    402 
    403 static reloc_howto_type *
    404 elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    405 			   const char *r_name)
    406 {
    407   unsigned int i;
    408 
    409   for (i = 0;
    410        i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]);
    411        i++)
    412     if (crx_elf_howto_table[i].name != NULL
    413 	&& strcasecmp (crx_elf_howto_table[i].name, r_name) == 0)
    414       return &crx_elf_howto_table[i];
    415 
    416   return NULL;
    417 }
    418 
    419 /* Retrieve a howto ptr using an internal relocation entry.  */
    420 
    421 static void
    422 elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
    423 		       Elf_Internal_Rela *dst)
    424 {
    425   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
    426   BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
    427   cache_ptr->howto = &crx_elf_howto_table[r_type];
    428 }
    429 
    430 /* Perform a relocation as part of a final link.  */
    431 
    432 static bfd_reloc_status_type
    433 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
    434 			     bfd *output_bfd ATTRIBUTE_UNUSED,
    435 			     asection *input_section, bfd_byte *contents,
    436 			     bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
    437 			     struct bfd_link_info *info ATTRIBUTE_UNUSED,
    438 			     asection *sec ATTRIBUTE_UNUSED,
    439 			     int is_local ATTRIBUTE_UNUSED)
    440 {
    441   unsigned short r_type = howto->type;
    442   bfd_byte *hit_data = contents + offset;
    443   bfd_vma reloc_bits, check;
    444 
    445   switch (r_type)
    446     {
    447      case R_CRX_IMM16:
    448      case R_CRX_IMM32:
    449      case R_CRX_ABS16:
    450      case R_CRX_ABS32:
    451      case R_CRX_REL8_CMP:
    452      case R_CRX_REL16:
    453      case R_CRX_REL24:
    454      case R_CRX_REL32:
    455      case R_CRX_REGREL12:
    456      case R_CRX_REGREL22:
    457      case R_CRX_REGREL28:
    458      case R_CRX_REGREL32:
    459        /* 'hit_data' is relative to the start of the instruction, not the
    460 	  relocation offset. Advance it to account for the exact offset.  */
    461        hit_data += 2;
    462        break;
    463 
    464      case R_CRX_REL4:
    465        /* This relocation type is used only in 'Branch if Equal to 0'
    466 	  instructions and requires special handling.  */
    467        Rvalue -= 1;
    468        break;
    469 
    470      case R_CRX_NONE:
    471        return bfd_reloc_ok;
    472        break;
    473 
    474      case R_CRX_SWITCH8:
    475      case R_CRX_SWITCH16:
    476      case R_CRX_SWITCH32:
    477        /* We only care about the addend, where the difference between
    478 	  expressions is kept.  */
    479        Rvalue = 0;
    480 
    481      default:
    482        break;
    483     }
    484 
    485   if (howto->pc_relative)
    486     {
    487       /* Subtract the address of the section containing the location.  */
    488       Rvalue -= (input_section->output_section->vma
    489 		 + input_section->output_offset);
    490       /* Subtract the position of the location within the section.  */
    491       Rvalue -= offset;
    492     }
    493 
    494   /* Add in supplied addend.  */
    495   Rvalue += addend;
    496 
    497   /* Complain if the bitfield overflows, whether it is considered
    498      as signed or unsigned.  */
    499   check = Rvalue >> howto->rightshift;
    500 
    501   /* Assumes two's complement.  This expression avoids
    502      overflow if howto->bitsize is the number of bits in
    503      bfd_vma.  */
    504   reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
    505 
    506   if (((bfd_vma) check & ~reloc_bits) != 0
    507       && (((bfd_vma) check & ~reloc_bits)
    508 	  != (-(bfd_vma) 1 & ~reloc_bits)))
    509     {
    510       /* The above right shift is incorrect for a signed
    511 	 value.  See if turning on the upper bits fixes the
    512 	 overflow.  */
    513       if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
    514 	{
    515 	  check |= ((bfd_vma) - 1
    516 		    & ~((bfd_vma) - 1
    517 			>> howto->rightshift));
    518 	  if (((bfd_vma) check & ~reloc_bits)
    519 	      != (-(bfd_vma) 1 & ~reloc_bits))
    520 	    return bfd_reloc_overflow;
    521 	}
    522       else
    523 	return bfd_reloc_overflow;
    524     }
    525 
    526   /* Drop unwanted bits from the value we are relocating to.  */
    527   Rvalue >>= (bfd_vma) howto->rightshift;
    528 
    529   /* Apply dst_mask to select only relocatable part of the insn.  */
    530   Rvalue &= howto->dst_mask;
    531 
    532   switch (howto->size)
    533     {
    534      case 0:
    535        if (r_type == R_CRX_REL4)
    536 	 {
    537 	   Rvalue <<= 4;
    538 	   Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
    539 	 }
    540 
    541        bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
    542        break;
    543 
    544      case 1:
    545        if (r_type == R_CRX_REGREL12)
    546 	 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
    547 
    548        bfd_put_16 (input_bfd, Rvalue, hit_data);
    549        break;
    550 
    551      case 2:
    552        if (r_type == R_CRX_REL24
    553 	   || r_type == R_CRX_REGREL22
    554 	   || r_type == R_CRX_REGREL28)
    555 	 Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
    556 		      bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
    557 
    558        if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
    559 	 /* Relocation on DATA is purely little-endian, that is, for a
    560 	    multi-byte datum, the lowest address in memory contains the
    561 	    little end of the datum, that is, the least significant byte.
    562 	    Therefore we use BFD's byte Putting functions.  */
    563 	 bfd_put_32 (input_bfd, Rvalue, hit_data);
    564        else
    565 	 /* Relocation on INSTRUCTIONS is different : Instructions are
    566 	    word-addressable, that is, each word itself is arranged according
    567 	    to little-endian convention, whereas the words are arranged with
    568 	    respect to one another in BIG ENDIAN fashion.
    569 	    When there is an immediate value that spans a word boundary, it is
    570 	    split in a big-endian way with respect to the words.  */
    571 	 {
    572 	   bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
    573 	   bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
    574 	 }
    575      break;
    576 
    577      default:
    578        return bfd_reloc_notsupported;
    579     }
    580 
    581   return bfd_reloc_ok;
    582 }
    583 
    584 /* Delete some bytes from a section while relaxing.  */
    585 
    586 static bfd_boolean
    587 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
    588 			      asection *sec, bfd_vma addr, int count)
    589 {
    590   Elf_Internal_Shdr *symtab_hdr;
    591   unsigned int sec_shndx;
    592   bfd_byte *contents;
    593   Elf_Internal_Rela *irel, *irelend;
    594   bfd_vma toaddr;
    595   Elf_Internal_Sym *isym;
    596   Elf_Internal_Sym *isymend;
    597   struct elf_link_hash_entry **sym_hashes;
    598   struct elf_link_hash_entry **end_hashes;
    599   struct elf_link_hash_entry **start_hashes;
    600   unsigned int symcount;
    601 
    602   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
    603 
    604   contents = elf_section_data (sec)->this_hdr.contents;
    605 
    606   toaddr = sec->size;
    607 
    608   irel = elf_section_data (sec)->relocs;
    609   irelend = irel + sec->reloc_count;
    610 
    611   /* Actually delete the bytes.  */
    612   memmove (contents + addr, contents + addr + count,
    613 	   (size_t) (toaddr - addr - count));
    614   sec->size -= count;
    615 
    616   /* Adjust all the relocs.  */
    617   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
    618     {
    619       /* Get the new reloc address.  */
    620       if ((irel->r_offset > addr
    621 	   && irel->r_offset < toaddr))
    622 	irel->r_offset -= count;
    623     }
    624 
    625   /* Adjust the local symbols defined in this section.  */
    626   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    627   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
    628   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
    629     {
    630       if (isym->st_shndx == sec_shndx
    631 	  && isym->st_value > addr
    632 	  && isym->st_value < toaddr)
    633 	{
    634 	  /* Adjust the addend of SWITCH relocations in this section,
    635 	     which reference this local symbol.  */
    636 	  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
    637 	    {
    638 	      unsigned long r_symndx;
    639 	      Elf_Internal_Sym *rsym;
    640 	      bfd_vma addsym, subsym;
    641 
    642 	      /* Skip if not a SWITCH relocation.  */
    643 	      if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
    644 		  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
    645 		  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
    646 		  continue;
    647 
    648 	      r_symndx = ELF32_R_SYM (irel->r_info);
    649 	      rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
    650 
    651 	      /* Skip if not the local adjusted symbol.  */
    652 	      if (rsym != isym)
    653 		continue;
    654 
    655 	      addsym = isym->st_value;
    656 	      subsym = addsym - irel->r_addend;
    657 
    658 	      /* Fix the addend only when -->> (addsym > addr >= subsym).  */
    659 	      if (subsym <= addr)
    660 		irel->r_addend -= count;
    661 	      else
    662 		continue;
    663 	    }
    664 
    665 	  isym->st_value -= count;
    666 	}
    667     }
    668 
    669   /* Now adjust the global symbols defined in this section.  */
    670   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
    671 	      - symtab_hdr->sh_info);
    672   sym_hashes = start_hashes = elf_sym_hashes (abfd);
    673   end_hashes = sym_hashes + symcount;
    674 
    675   for (; sym_hashes < end_hashes; sym_hashes++)
    676     {
    677       struct elf_link_hash_entry *sym_hash = *sym_hashes;
    678 
    679       /* The '--wrap SYMBOL' option is causing a pain when the object file,
    680 	 containing the definition of __wrap_SYMBOL, includes a direct
    681 	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
    682 	 the same symbol (which is __wrap_SYMBOL), but still exist as two
    683 	 different symbols in 'sym_hashes', we don't want to adjust
    684 	 the global symbol __wrap_SYMBOL twice.
    685 	 This check is only relevant when symbols are being wrapped.  */
    686       if (link_info->wrap_hash != NULL)
    687 	{
    688 	  struct elf_link_hash_entry **cur_sym_hashes;
    689 
    690 	  /* Loop only over the symbols whom been already checked.  */
    691 	  for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
    692 	       cur_sym_hashes++)
    693 	    {
    694 	      /* If the current symbol is identical to 'sym_hash', that means
    695 		 the symbol was already adjusted (or at least checked).  */
    696 	      if (*cur_sym_hashes == sym_hash)
    697 		break;
    698 	    }
    699 	  /* Don't adjust the symbol again.  */
    700 	  if (cur_sym_hashes < sym_hashes)
    701 	    continue;
    702 	}
    703 
    704       if ((sym_hash->root.type == bfd_link_hash_defined
    705 	   || sym_hash->root.type == bfd_link_hash_defweak)
    706 	  && sym_hash->root.u.def.section == sec
    707 	  && sym_hash->root.u.def.value > addr
    708 	  && sym_hash->root.u.def.value < toaddr)
    709 	sym_hash->root.u.def.value -= count;
    710     }
    711 
    712   return TRUE;
    713 }
    714 
    715 /* This is a version of bfd_generic_get_relocated_section_contents
    716    which uses elf32_crx_relocate_section.  */
    717 
    718 static bfd_byte *
    719 elf32_crx_get_relocated_section_contents (bfd *output_bfd,
    720 					  struct bfd_link_info *link_info,
    721 					  struct bfd_link_order *link_order,
    722 					  bfd_byte *data,
    723 					  bfd_boolean relocatable,
    724 					  asymbol **symbols)
    725 {
    726   Elf_Internal_Shdr *symtab_hdr;
    727   asection *input_section = link_order->u.indirect.section;
    728   bfd *input_bfd = input_section->owner;
    729   asection **sections = NULL;
    730   Elf_Internal_Rela *internal_relocs = NULL;
    731   Elf_Internal_Sym *isymbuf = NULL;
    732 
    733   /* We only need to handle the case of relaxing, or of having a
    734      particular set of section contents, specially.  */
    735   if (relocatable
    736       || elf_section_data (input_section)->this_hdr.contents == NULL)
    737     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
    738 						       link_order, data,
    739 						       relocatable,
    740 						       symbols);
    741 
    742   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    743 
    744   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
    745 	  (size_t) input_section->size);
    746 
    747   if ((input_section->flags & SEC_RELOC) != 0
    748       && input_section->reloc_count > 0)
    749     {
    750       Elf_Internal_Sym *isym;
    751       Elf_Internal_Sym *isymend;
    752       asection **secpp;
    753       bfd_size_type amt;
    754 
    755       internal_relocs = (_bfd_elf_link_read_relocs
    756 			 (input_bfd, input_section, NULL,
    757 			  (Elf_Internal_Rela *) NULL, FALSE));
    758       if (internal_relocs == NULL)
    759 	goto error_return;
    760 
    761       if (symtab_hdr->sh_info != 0)
    762 	{
    763 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
    764 	  if (isymbuf == NULL)
    765 	    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
    766 					    symtab_hdr->sh_info, 0,
    767 					    NULL, NULL, NULL);
    768 	  if (isymbuf == NULL)
    769 	    goto error_return;
    770 	}
    771 
    772       amt = symtab_hdr->sh_info;
    773       amt *= sizeof (asection *);
    774       sections = bfd_malloc (amt);
    775       if (sections == NULL && amt != 0)
    776 	goto error_return;
    777 
    778       isymend = isymbuf + symtab_hdr->sh_info;
    779       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
    780 	{
    781 	  asection *isec;
    782 
    783 	  if (isym->st_shndx == SHN_UNDEF)
    784 	    isec = bfd_und_section_ptr;
    785 	  else if (isym->st_shndx == SHN_ABS)
    786 	    isec = bfd_abs_section_ptr;
    787 	  else if (isym->st_shndx == SHN_COMMON)
    788 	    isec = bfd_com_section_ptr;
    789 	  else
    790 	    isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
    791 
    792 	  *secpp = isec;
    793 	}
    794 
    795       if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
    796 				     input_section, data, internal_relocs,
    797 				     isymbuf, sections))
    798 	goto error_return;
    799 
    800       if (sections != NULL)
    801 	free (sections);
    802       if (isymbuf != NULL
    803 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
    804 	free (isymbuf);
    805       if (elf_section_data (input_section)->relocs != internal_relocs)
    806 	free (internal_relocs);
    807     }
    808 
    809   return data;
    810 
    811  error_return:
    812   if (sections != NULL)
    813     free (sections);
    814   if (isymbuf != NULL
    815       && symtab_hdr->contents != (unsigned char *) isymbuf)
    816     free (isymbuf);
    817   if (internal_relocs != NULL
    818       && elf_section_data (input_section)->relocs != internal_relocs)
    819     free (internal_relocs);
    820   return NULL;
    821 }
    822 
    823 /* Relocate a CRX ELF section.  */
    824 
    825 static bfd_boolean
    826 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
    827 			    bfd *input_bfd, asection *input_section,
    828 			    bfd_byte *contents, Elf_Internal_Rela *relocs,
    829 			    Elf_Internal_Sym *local_syms,
    830 			    asection **local_sections)
    831 {
    832   Elf_Internal_Shdr *symtab_hdr;
    833   struct elf_link_hash_entry **sym_hashes;
    834   Elf_Internal_Rela *rel, *relend;
    835 
    836   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    837   sym_hashes = elf_sym_hashes (input_bfd);
    838 
    839   rel = relocs;
    840   relend = relocs + input_section->reloc_count;
    841   for (; rel < relend; rel++)
    842     {
    843       int r_type;
    844       reloc_howto_type *howto;
    845       unsigned long r_symndx;
    846       Elf_Internal_Sym *sym;
    847       asection *sec;
    848       struct elf_link_hash_entry *h;
    849       bfd_vma relocation;
    850       bfd_reloc_status_type r;
    851 
    852       r_symndx = ELF32_R_SYM (rel->r_info);
    853       r_type = ELF32_R_TYPE (rel->r_info);
    854       howto = crx_elf_howto_table + (r_type);
    855 
    856       h = NULL;
    857       sym = NULL;
    858       sec = NULL;
    859       if (r_symndx < symtab_hdr->sh_info)
    860 	{
    861 	  sym = local_syms + r_symndx;
    862 	  sec = local_sections[r_symndx];
    863 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
    864 	}
    865       else
    866 	{
    867 	  bfd_boolean unresolved_reloc, warned, ignored;
    868 
    869 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    870 				   r_symndx, symtab_hdr, sym_hashes,
    871 				   h, sec, relocation,
    872 				   unresolved_reloc, warned, ignored);
    873 	}
    874 
    875       if (sec != NULL && discarded_section (sec))
    876 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    877 					 rel, 1, relend, howto, 0, contents);
    878 
    879       if (info->relocatable)
    880 	continue;
    881 
    882       r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
    883 					input_section,
    884 					contents, rel->r_offset,
    885 					relocation, rel->r_addend,
    886 					info, sec, h == NULL);
    887 
    888       if (r != bfd_reloc_ok)
    889 	{
    890 	  const char *name;
    891 	  const char *msg = (const char *) 0;
    892 
    893 	  if (h != NULL)
    894 	    name = h->root.root.string;
    895 	  else
    896 	    {
    897 	      name = (bfd_elf_string_from_elf_section
    898 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
    899 	      if (name == NULL || *name == '\0')
    900 		name = bfd_section_name (input_bfd, sec);
    901 	    }
    902 
    903 	  switch (r)
    904 	    {
    905 	     case bfd_reloc_overflow:
    906 	       if (!((*info->callbacks->reloc_overflow)
    907 		     (info, (h ? &h->root : NULL), name, howto->name,
    908 		      (bfd_vma) 0, input_bfd, input_section,
    909 		      rel->r_offset)))
    910 		 return FALSE;
    911 	       break;
    912 
    913 	     case bfd_reloc_undefined:
    914 	       if (!((*info->callbacks->undefined_symbol)
    915 		     (info, name, input_bfd, input_section,
    916 		      rel->r_offset, TRUE)))
    917 		 return FALSE;
    918 	       break;
    919 
    920 	     case bfd_reloc_outofrange:
    921 	       msg = _("internal error: out of range error");
    922 	       goto common_error;
    923 
    924 	     case bfd_reloc_notsupported:
    925 	       msg = _("internal error: unsupported relocation error");
    926 	       goto common_error;
    927 
    928 	     case bfd_reloc_dangerous:
    929 	       msg = _("internal error: dangerous error");
    930 	       goto common_error;
    931 
    932 	     default:
    933 	       msg = _("internal error: unknown error");
    934 	       /* Fall through.  */
    935 
    936 	     common_error:
    937 	       if (!((*info->callbacks->warning)
    938 		     (info, msg, name, input_bfd, input_section,
    939 		      rel->r_offset)))
    940 		 return FALSE;
    941 	       break;
    942 	    }
    943 	}
    944     }
    945 
    946   return TRUE;
    947 }
    948 
    949 /* This function handles relaxing for the CRX.
    950 
    951    There's quite a few relaxing opportunites available on the CRX:
    952 
    953 	* bal/bcond:32 -> bal/bcond:16				   2 bytes
    954 	* bcond:16 -> bcond:8					   2 bytes
    955 	* cmpbcond:24 -> cmpbcond:8				   2 bytes
    956 	* arithmetic imm32 -> arithmetic imm16			   2 bytes
    957 
    958    Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
    959 
    960 static bfd_boolean
    961 elf32_crx_relax_section (bfd *abfd, asection *sec,
    962 			 struct bfd_link_info *link_info, bfd_boolean *again)
    963 {
    964   Elf_Internal_Shdr *symtab_hdr;
    965   Elf_Internal_Rela *internal_relocs;
    966   Elf_Internal_Rela *irel, *irelend;
    967   bfd_byte *contents = NULL;
    968   Elf_Internal_Sym *isymbuf = NULL;
    969 
    970   /* Assume nothing changes.  */
    971   *again = FALSE;
    972 
    973   /* We don't have to do anything for a relocatable link, if
    974      this section does not have relocs, or if this is not a
    975      code section.  */
    976   if (link_info->relocatable
    977       || (sec->flags & SEC_RELOC) == 0
    978       || sec->reloc_count == 0
    979       || (sec->flags & SEC_CODE) == 0)
    980     return TRUE;
    981 
    982   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    983 
    984   /* Get a copy of the native relocations.  */
    985   internal_relocs = (_bfd_elf_link_read_relocs
    986 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
    987 		      link_info->keep_memory));
    988   if (internal_relocs == NULL)
    989     goto error_return;
    990 
    991   /* Walk through them looking for relaxing opportunities.  */
    992   irelend = internal_relocs + sec->reloc_count;
    993   for (irel = internal_relocs; irel < irelend; irel++)
    994     {
    995       bfd_vma symval;
    996 
    997       /* If this isn't something that can be relaxed, then ignore
    998 	 this reloc.  */
    999       if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
   1000 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
   1001 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
   1002 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
   1003 	continue;
   1004 
   1005       /* Get the section contents if we haven't done so already.  */
   1006       if (contents == NULL)
   1007 	{
   1008 	  /* Get cached copy if it exists.  */
   1009 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
   1010 	    contents = elf_section_data (sec)->this_hdr.contents;
   1011 	  /* Go get them off disk.  */
   1012 	  else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
   1013 	    goto error_return;
   1014 	}
   1015 
   1016       /* Read this BFD's local symbols if we haven't done so already.  */
   1017       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
   1018 	{
   1019 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1020 	  if (isymbuf == NULL)
   1021 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
   1022 					    symtab_hdr->sh_info, 0,
   1023 					    NULL, NULL, NULL);
   1024 	  if (isymbuf == NULL)
   1025 	    goto error_return;
   1026 	}
   1027 
   1028       /* Get the value of the symbol referred to by the reloc.  */
   1029       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
   1030 	{
   1031 	  /* A local symbol.  */
   1032 	  Elf_Internal_Sym *isym;
   1033 	  asection *sym_sec;
   1034 
   1035 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
   1036 	  if (isym->st_shndx == SHN_UNDEF)
   1037 	    sym_sec = bfd_und_section_ptr;
   1038 	  else if (isym->st_shndx == SHN_ABS)
   1039 	    sym_sec = bfd_abs_section_ptr;
   1040 	  else if (isym->st_shndx == SHN_COMMON)
   1041 	    sym_sec = bfd_com_section_ptr;
   1042 	  else
   1043 	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
   1044 	  symval = (isym->st_value
   1045 		    + sym_sec->output_section->vma
   1046 		    + sym_sec->output_offset);
   1047 	}
   1048       else
   1049 	{
   1050 	  unsigned long indx;
   1051 	  struct elf_link_hash_entry *h;
   1052 
   1053 	  /* An external symbol.  */
   1054 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
   1055 	  h = elf_sym_hashes (abfd)[indx];
   1056 	  BFD_ASSERT (h != NULL);
   1057 
   1058 	  if (h->root.type != bfd_link_hash_defined
   1059 	      && h->root.type != bfd_link_hash_defweak)
   1060 	    /* This appears to be a reference to an undefined
   1061 	       symbol.  Just ignore it--it will be caught by the
   1062 	       regular reloc processing.  */
   1063 	    continue;
   1064 
   1065 	  symval = (h->root.u.def.value
   1066 		    + h->root.u.def.section->output_section->vma
   1067 		    + h->root.u.def.section->output_offset);
   1068 	}
   1069 
   1070       /* For simplicity of coding, we are going to modify the section
   1071 	 contents, the section relocs, and the BFD symbol table.  We
   1072 	 must tell the rest of the code not to free up this
   1073 	 information.  It would be possible to instead create a table
   1074 	 of changes which have to be made, as is done in coff-mips.c;
   1075 	 that would be more work, but would require less memory when
   1076 	 the linker is run.  */
   1077 
   1078       /* Try to turn a 32bit pc-relative branch/call into
   1079 	 a 16bit pc-relative branch/call.  */
   1080       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
   1081 	{
   1082 	  bfd_vma value = symval;
   1083 
   1084 	  /* Deal with pc-relative gunk.  */
   1085 	  value -= (sec->output_section->vma + sec->output_offset);
   1086 	  value -= irel->r_offset;
   1087 	  value += irel->r_addend;
   1088 
   1089 	  /* See if the value will fit in 16 bits, note the high value is
   1090 	     0xfffe + 2 as the target will be two bytes closer if we are
   1091 	     able to relax.  */
   1092 	  if ((long) value < 0x10000 && (long) value > -0x10002)
   1093 	    {
   1094 	      unsigned short code;
   1095 
   1096 	      /* Get the opcode.  */
   1097 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   1098 
   1099 	      /* Verify it's a 'bal'/'bcond' and fix the opcode.  */
   1100 	      if ((code & 0xfff0) == 0x3170)
   1101 		bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
   1102 	      else if ((code & 0xf0ff) == 0x707f)
   1103 		bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
   1104 	      else
   1105 		continue;
   1106 
   1107 	      /* Note that we've changed the relocs, section contents, etc.  */
   1108 	      elf_section_data (sec)->relocs = internal_relocs;
   1109 	      elf_section_data (sec)->this_hdr.contents = contents;
   1110 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1111 
   1112 	      /* Fix the relocation's type.  */
   1113 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1114 					   R_CRX_REL16);
   1115 
   1116 	      /* Delete two bytes of data.  */
   1117 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
   1118 						   irel->r_offset + 2, 2))
   1119 		goto error_return;
   1120 
   1121 	      /* That will change things, so, we should relax again.
   1122 		 Note that this is not required, and it may be slow.  */
   1123 	      *again = TRUE;
   1124 	    }
   1125 	}
   1126 
   1127       /* Try to turn a 16bit pc-relative branch into an
   1128 	 8bit pc-relative branch.  */
   1129       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
   1130 	{
   1131 	  bfd_vma value = symval;
   1132 
   1133 	  /* Deal with pc-relative gunk.  */
   1134 	  value -= (sec->output_section->vma + sec->output_offset);
   1135 	  value -= irel->r_offset;
   1136 	  value += irel->r_addend;
   1137 
   1138 	  /* See if the value will fit in 8 bits, note the high value is
   1139 	     0xfc + 2 as the target will be two bytes closer if we are
   1140 	     able to relax.  */
   1141 	  if ((long) value < 0xfe && (long) value > -0x100)
   1142 	    {
   1143 	      unsigned short code;
   1144 
   1145 	      /* Get the opcode.  */
   1146 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   1147 
   1148 	      /* Verify it's a 'bcond' opcode.  */
   1149 	      if ((code & 0xf0ff) != 0x707e)
   1150 		continue;
   1151 
   1152 	      /* Note that we've changed the relocs, section contents, etc.  */
   1153 	      elf_section_data (sec)->relocs = internal_relocs;
   1154 	      elf_section_data (sec)->this_hdr.contents = contents;
   1155 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1156 
   1157 	      /* Fix the relocation's type.  */
   1158 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1159 					   R_CRX_REL8);
   1160 
   1161 	      /* Delete two bytes of data.  */
   1162 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
   1163 						   irel->r_offset + 2, 2))
   1164 		goto error_return;
   1165 
   1166 	      /* That will change things, so, we should relax again.
   1167 		 Note that this is not required, and it may be slow.  */
   1168 	      *again = TRUE;
   1169 	    }
   1170 	}
   1171 
   1172       /* Try to turn a 24bit pc-relative cmp&branch into
   1173 	 an 8bit pc-relative cmp&branch.  */
   1174       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
   1175 	{
   1176 	  bfd_vma value = symval;
   1177 
   1178 	  /* Deal with pc-relative gunk.  */
   1179 	  value -= (sec->output_section->vma + sec->output_offset);
   1180 	  value -= irel->r_offset;
   1181 	  value += irel->r_addend;
   1182 
   1183 	  /* See if the value will fit in 8 bits, note the high value is
   1184 	     0x7e + 2 as the target will be two bytes closer if we are
   1185 	     able to relax.  */
   1186 	  if ((long) value < 0x100 && (long) value > -0x100)
   1187 	    {
   1188 	      unsigned short code;
   1189 
   1190 	      /* Get the opcode.  */
   1191 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   1192 
   1193 	      /* Verify it's a 'cmp&branch' opcode.  */
   1194 	      if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
   1195 	       && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
   1196 	       && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
   1197 	       /* Or a Co-processor branch ('bcop').  */
   1198 	       && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
   1199 		continue;
   1200 
   1201 	      /* Note that we've changed the relocs, section contents, etc.  */
   1202 	      elf_section_data (sec)->relocs = internal_relocs;
   1203 	      elf_section_data (sec)->this_hdr.contents = contents;
   1204 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1205 
   1206 	      /* Fix the opcode.  */
   1207 	      bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
   1208 
   1209 	      /* Fix the relocation's type.  */
   1210 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1211 					   R_CRX_REL8_CMP);
   1212 
   1213 	      /* Delete two bytes of data.  */
   1214 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
   1215 						   irel->r_offset + 4, 2))
   1216 		goto error_return;
   1217 
   1218 	      /* That will change things, so, we should relax again.
   1219 		 Note that this is not required, and it may be slow.  */
   1220 	      *again = TRUE;
   1221 	    }
   1222 	}
   1223 
   1224       /* Try to turn a 32bit immediate address into
   1225 	 a 16bit immediate address.  */
   1226       if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
   1227 	{
   1228 	  bfd_vma value = symval;
   1229 
   1230 	  /* See if the value will fit in 16 bits.  */
   1231 	  if ((long) value < 0x7fff && (long) value > -0x8000)
   1232 	    {
   1233 	      unsigned short code;
   1234 
   1235 	      /* Get the opcode.  */
   1236 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   1237 
   1238 	      /* Verify it's a 'arithmetic double'.  */
   1239 	      if ((code & 0xf0f0) != 0x20f0)
   1240 		continue;
   1241 
   1242 	      /* Note that we've changed the relocs, section contents, etc.  */
   1243 	      elf_section_data (sec)->relocs = internal_relocs;
   1244 	      elf_section_data (sec)->this_hdr.contents = contents;
   1245 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1246 
   1247 	      /* Fix the opcode.  */
   1248 	      bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
   1249 
   1250 	      /* Fix the relocation's type.  */
   1251 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1252 					   R_CRX_IMM16);
   1253 
   1254 	      /* Delete two bytes of data.  */
   1255 	      if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
   1256 						   irel->r_offset + 2, 2))
   1257 		goto error_return;
   1258 
   1259 	      /* That will change things, so, we should relax again.
   1260 		 Note that this is not required, and it may be slow.  */
   1261 	      *again = TRUE;
   1262 	    }
   1263 	}
   1264     }
   1265 
   1266   if (isymbuf != NULL
   1267       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1268     {
   1269       if (! link_info->keep_memory)
   1270 	free (isymbuf);
   1271       else
   1272 	{
   1273 	  /* Cache the symbols for elf_link_input_bfd.  */
   1274 	  symtab_hdr->contents = (unsigned char *) isymbuf;
   1275 	}
   1276     }
   1277 
   1278   if (contents != NULL
   1279       && elf_section_data (sec)->this_hdr.contents != contents)
   1280     {
   1281       if (! link_info->keep_memory)
   1282 	free (contents);
   1283       else
   1284 	{
   1285 	  /* Cache the section contents for elf_link_input_bfd.  */
   1286 	  elf_section_data (sec)->this_hdr.contents = contents;
   1287 	}
   1288     }
   1289 
   1290   if (internal_relocs != NULL
   1291       && elf_section_data (sec)->relocs != internal_relocs)
   1292     free (internal_relocs);
   1293 
   1294   return TRUE;
   1295 
   1296  error_return:
   1297   if (isymbuf != NULL
   1298       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1299     free (isymbuf);
   1300   if (contents != NULL
   1301       && elf_section_data (sec)->this_hdr.contents != contents)
   1302     free (contents);
   1303   if (internal_relocs != NULL
   1304       && elf_section_data (sec)->relocs != internal_relocs)
   1305     free (internal_relocs);
   1306 
   1307   return FALSE;
   1308 }
   1309 
   1310 /* Definitions for setting CRX target vector.  */
   1311 #define TARGET_LITTLE_SYM		crx_elf32_vec
   1312 #define TARGET_LITTLE_NAME		"elf32-crx"
   1313 #define ELF_ARCH			bfd_arch_crx
   1314 #define ELF_MACHINE_CODE		EM_CRX
   1315 #define ELF_MAXPAGESIZE			0x1
   1316 #define elf_symbol_leading_char		'_'
   1317 
   1318 #define bfd_elf32_bfd_reloc_type_lookup	elf_crx_reloc_type_lookup
   1319 #define bfd_elf32_bfd_reloc_name_lookup \
   1320 					elf_crx_reloc_name_lookup
   1321 #define elf_info_to_howto		elf_crx_info_to_howto
   1322 #define elf_info_to_howto_rel		0
   1323 #define elf_backend_relocate_section	elf32_crx_relocate_section
   1324 #define bfd_elf32_bfd_relax_section	elf32_crx_relax_section
   1325 #define bfd_elf32_bfd_get_relocated_section_contents \
   1326 				elf32_crx_get_relocated_section_contents
   1327 #define elf_backend_can_gc_sections     1
   1328 #define elf_backend_rela_normal		1
   1329 
   1330 #include "elf32-target.h"
   1331