Home | History | Annotate | Download | only in bfd
      1 /* BFD back-end for National Semiconductor's CR16C ELF
      2    Copyright (C) 2004-2014 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "libbfd.h"
     24 #include "bfdlink.h"
     25 #include "elf/cr16c.h"
     26 #include "elf-bfd.h"
     27 
     28 
     29 #define USE_REL	1	/* CR16C uses REL relocations instead of RELA.  */
     30 
     31 /* The following definition is based on EMPTY_HOWTO macro,
     32    but also initiates the "name" field in HOWTO struct.  */
     33 #define ONLY_NAME_HOWTO(C) \
     34   HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
     35 	  STRINGX(C), FALSE, 0, 0, FALSE)
     36 
     37 /* reloc_map_index array maps CRASM relocation type into a BFD
     38    relocation enum. The array's indices are synchronized with
     39    RINDEX_16C_* indices, created in include/elf/cr16c.h.
     40    The array is used in:
     41    1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup().
     42    2. asreloc.c : find_reloc_type(). */
     43 
     44 RELOC_MAP reloc_map_index[RINDEX_16C_MAX] =
     45 {
     46   {R_16C_NUM08,     BFD_RELOC_16C_NUM08},
     47   {R_16C_NUM08_C,   BFD_RELOC_16C_NUM08_C},
     48   {R_16C_NUM16,     BFD_RELOC_16C_NUM16},
     49   {R_16C_NUM16_C,   BFD_RELOC_16C_NUM16_C},
     50   {R_16C_NUM32,     BFD_RELOC_16C_NUM32},
     51   {R_16C_NUM32_C,   BFD_RELOC_16C_NUM32_C},
     52   {R_16C_DISP04,    BFD_RELOC_16C_DISP04},
     53   {R_16C_DISP04_C,  BFD_RELOC_16C_DISP04_C},
     54   {R_16C_DISP08,    BFD_RELOC_16C_DISP08},
     55   {R_16C_DISP08_C,  BFD_RELOC_16C_DISP08_C},
     56   {R_16C_DISP16,    BFD_RELOC_16C_DISP16},
     57   {R_16C_DISP16_C,  BFD_RELOC_16C_DISP16_C},
     58   {R_16C_DISP24,    BFD_RELOC_16C_DISP24},
     59   {R_16C_DISP24_C,  BFD_RELOC_16C_DISP24_C},
     60   {R_16C_DISP24a,   BFD_RELOC_16C_DISP24a},
     61   {R_16C_DISP24a_C, BFD_RELOC_16C_DISP24a_C},
     62   {R_16C_REG04,     BFD_RELOC_16C_REG04},
     63   {R_16C_REG04_C,   BFD_RELOC_16C_REG04_C},
     64   {R_16C_REG04a,    BFD_RELOC_16C_REG04a},
     65   {R_16C_REG04a_C,  BFD_RELOC_16C_REG04a_C},
     66   {R_16C_REG14,     BFD_RELOC_16C_REG14},
     67   {R_16C_REG14_C,   BFD_RELOC_16C_REG14_C},
     68   {R_16C_REG16,     BFD_RELOC_16C_REG16},
     69   {R_16C_REG16_C,   BFD_RELOC_16C_REG16_C},
     70   {R_16C_REG20,     BFD_RELOC_16C_REG20},
     71   {R_16C_REG20_C,   BFD_RELOC_16C_REG20_C},
     72   {R_16C_ABS20,     BFD_RELOC_16C_ABS20},
     73   {R_16C_ABS20_C,   BFD_RELOC_16C_ABS20_C},
     74   {R_16C_ABS24,     BFD_RELOC_16C_ABS24},
     75   {R_16C_ABS24_C,   BFD_RELOC_16C_ABS24_C},
     76   {R_16C_IMM04,     BFD_RELOC_16C_IMM04},
     77   {R_16C_IMM04_C,   BFD_RELOC_16C_IMM04_C},
     78   {R_16C_IMM16,     BFD_RELOC_16C_IMM16},
     79   {R_16C_IMM16_C,   BFD_RELOC_16C_IMM16_C},
     80   {R_16C_IMM20,     BFD_RELOC_16C_IMM20},
     81   {R_16C_IMM20_C,   BFD_RELOC_16C_IMM20_C},
     82   {R_16C_IMM24,     BFD_RELOC_16C_IMM24},
     83   {R_16C_IMM24_C,   BFD_RELOC_16C_IMM24_C},
     84   {R_16C_IMM32,     BFD_RELOC_16C_IMM32},
     85   {R_16C_IMM32_C,   BFD_RELOC_16C_IMM32_C}
     86 };
     87 
     88 static reloc_howto_type elf_howto_table[] =
     89 {
     90   /* 00 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08),
     91   /* 01 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08_C),
     92   /* 02 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16),
     93   /* 03 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16_C),
     94   /* 04 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32),
     95   /* 05 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32_C),
     96   /* 06 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04),
     97   /* 07 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04_C),
     98   /* 08 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08),
     99   /* 09 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08_C),
    100   /* 10 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16),
    101   /* 11 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16_C),
    102   /* 12 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24),
    103   /* 13 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24_C),
    104   /* 14 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a),
    105   /* 15 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a_C),
    106   /* 16 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04),
    107   /* 17 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04_C),
    108   /* 18 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a),
    109   /* 19 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a_C),
    110   /* 20 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14),
    111   /* 21 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14_C),
    112   /* 22 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16),
    113   /* 23 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16_C),
    114   /* 24 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20),
    115   /* 25 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20_C),
    116   /* 26 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20),
    117   /* 27 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20_C),
    118   /* 28 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24),
    119   /* 29 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24_C),
    120   /* 30 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04),
    121   /* 31 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04_C),
    122   /* 32 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16),
    123   /* 33 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16_C),
    124   /* 34 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20),
    125   /* 35 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20_C),
    126   /* 36 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24),
    127   /* 37 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24_C),
    128   /* 38 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32),
    129   /* 39 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32_C)
    130 };
    131 
    132 
    133 /* Code to turn a code_type into a howto ptr, uses the above howto table.  */
    134 
    135 static reloc_howto_type *
    136 elf_cr16c_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    137 			     bfd_reloc_code_real_type code)
    138 {
    139   unsigned int i;
    140 
    141   for (i = 0; i < RINDEX_16C_MAX; i++)
    142     {
    143       if (code == reloc_map_index[i].bfd_reloc_enum)
    144 	{
    145 	  /* printf ("CR16C Relocation Type is - %x\n", code); */
    146 	  return & elf_howto_table[i];
    147 	}
    148     }
    149 
    150   /* printf ("This relocation Type is not supported - %x\n", code); */
    151   return 0;
    152 }
    153 
    154 static reloc_howto_type *
    155 elf_cr16c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    156 			     const char *r_name)
    157 {
    158   unsigned int i;
    159 
    160   for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
    161     if (elf_howto_table[i].name != NULL
    162 	&& strcasecmp (elf_howto_table[i].name, r_name) == 0)
    163       return &elf_howto_table[i];
    164 
    165   return NULL;
    166 }
    167 
    168 static void
    169 elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
    170 			 arelent *cache_ptr ATTRIBUTE_UNUSED,
    171 			 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
    172 {
    173   abort ();
    174 }
    175 
    176 static void
    177 elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
    178 			     arelent *cache_ptr,
    179 			     Elf_Internal_Rela *dst)
    180 {
    181   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
    182 
    183   BFD_ASSERT (r_type < (unsigned int) RINDEX_16C_MAX);
    184   cache_ptr->howto = &elf_howto_table[r_type];
    185 }
    186 
    187 /* Perform a relocation as part of a final link.  */
    188 
    189 static bfd_reloc_status_type
    190 cr16c_elf_final_link_relocate (reloc_howto_type *howto,
    191 			       bfd *abfd,
    192 			       bfd *output_bfd ATTRIBUTE_UNUSED,
    193 			       asection *input_section,
    194 			       bfd_byte *data,
    195 			       bfd_vma octets,
    196 			       bfd_vma Rvalue,
    197 			       bfd_vma addend ATTRIBUTE_UNUSED,
    198 			       struct bfd_link_info *info ATTRIBUTE_UNUSED,
    199 			       asection *sym_sec ATTRIBUTE_UNUSED,
    200 			       int is_local ATTRIBUTE_UNUSED)
    201 {
    202   long value;
    203   short sword;			/* Extracted from the hole and put back.  */
    204   unsigned long format, addr_type, code_factor;
    205   unsigned short size;
    206   unsigned short r_type;
    207 
    208   unsigned long disp20_opcod;
    209   char neg = 0;
    210   char neg2pos = 0;
    211 
    212   long left_val = 0;
    213   long plus_factor = 0;		/* To be added to the hole.  */
    214 
    215 #define MIN_BYTE	((int) 0xFFFFFF80)
    216 #define MIN_WORD	((int) 0xFFFF8000)
    217 #define	MAX_UWORD	((unsigned) 0x0000FFFF)
    218 #define	MAX_UBYTE	((unsigned) 0x000000FF)
    219 
    220   r_type = reloc_map_index[howto->type].cr_reloc_type;
    221   format = r_type & R_FORMAT;
    222   size = r_type & R_SIZESP;
    223   addr_type = r_type & R_ADDRTYPE;
    224   code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
    225 
    226   switch (format)
    227     {
    228     case R_NUMBER:
    229       switch (size)
    230 	{
    231 	case R_S_16C_08: 	/* One byte.  */
    232 	  value = bfd_get_8 (abfd, (char *) data + octets);
    233 	  break;
    234 	case R_S_16C_16: 	/* Two bytes. */
    235 	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
    236 	  value = sword;
    237 	  break;
    238 	case R_S_16C_32:	/* Four bytes.  */
    239 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    240 	  break;
    241 	default:
    242 	  return bfd_reloc_notsupported;
    243 	}
    244       break;
    245 
    246     case R_16C_DISPL:
    247       switch (size)
    248 	{
    249 	case R_S_16C_04:    /* word1(4-7).  */
    250 	  value = bfd_get_8 (abfd, (char *) data + octets);
    251 	  left_val = value & 0xF;
    252 	  value = (value & 0xF0) >> 4;
    253 	  value++;
    254 	  value <<= 1;
    255 	  break;
    256 	case R_S_16C_08:    /* word1(0-3,8-11).  */
    257 	  sword = bfd_get_16 (abfd, (char *) data + octets);
    258 	  value = sword & 0x000F;
    259 	  value |= ((sword & 0x0F00) >> 4);
    260 	  left_val = sword & 0xF0F0;
    261 	  value <<= 1;
    262 	  if (value & 0x100)
    263 	    value |= 0xFFFFFF00;
    264 	  break;
    265 	case R_S_16C_16:    /* word2.  */
    266 	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
    267 	  value = sword;
    268 	  value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15);
    269 	  value <<= 1;
    270 	  if (value & 0x10000)
    271 	    value |= 0xFFFF0000;
    272 	  break;
    273 	case R_S_16C_24_a:	/* word1(0-7),word2.  */
    274 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    275 	  left_val = value & 0x0000FF00;
    276 	  value = ((value & 0xFFFE0000) >> 17) |
    277 	    ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15);
    278 	  value <<= 1;
    279 	  if (value & 0x1000000)
    280 	    value |= 0xFE000000;
    281 	  break;
    282 	case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
    283 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    284 	  left_val = value & 0x0000F0F0;
    285 	  value = ((value >> 16) & 0x0000FFFF) |
    286 	    ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
    287 
    288 	  value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23);
    289 
    290 	  value <<= 1;
    291 	  if (value & 0x1000000)
    292 	    value |= 0xFE000000;
    293 	  break;
    294 	default:
    295 	  return bfd_reloc_notsupported;
    296 	}
    297       break;
    298 
    299     case R_16C_REGREL:
    300       switch (size)
    301 	{
    302 	case R_S_16C_04:    /* word1(12-15) not scaled.  */
    303 	  value = bfd_get_8 (abfd, (char *) data + octets);
    304 	  left_val = value & 0xF0;
    305 	  value = value & 0xF;
    306 	  break;
    307 	case R_S_16C_04_a:	/* word1(12-15) scaled by 2.  */
    308 	  value = bfd_get_8 (abfd, (char *) data + octets);
    309 	  left_val = value & 0xF0;
    310 	  value = value & 0xF;
    311 	  value <<= 1;
    312 	  break;
    313 	case R_S_16C_14:    /* word1(4-5),word2(0-3,8-15).  */
    314 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    315 	  left_val = value & 0x00F0FFCF;
    316 	  value = ((value & 0xc0000000) >> 24) |
    317 	    ((value & 0x3F000000) >> 16) |
    318 	    ((value & 0x000F0000) >> 16) | (value & 0x00000030);
    319 	  break;
    320 	case R_S_16C_16:    /* word2.  */
    321 	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
    322 	  value = sword;
    323 	  break;
    324 	case R_S_16C_20:    /* word2(8-11),word3.  */
    325 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    326 	  left_val = value & 0xF0;
    327 	  value = (value & 0xF) << 16;
    328 	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1);
    329 	  value = value | (unsigned short) sword;
    330 	  disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3);
    331 	  disp20_opcod |= 0x0FFF0000;
    332 	  if ((disp20_opcod == 0x4FFF0018) ||	/* loadb -disp20(reg) */
    333 	      (disp20_opcod == 0x5FFF0018) ||	/* loadb -disp20(rp)  */
    334 	      (disp20_opcod == 0x8FFF0018) ||	/* loadd -disp20(reg) */
    335 	      (disp20_opcod == 0x9FFF0018) ||	/* loadd -disp20(rp)  */
    336 	      (disp20_opcod == 0xCFFF0018) ||	/* loadw -disp20(reg) */
    337 	      (disp20_opcod == 0xDFFF0018) ||	/* loadw -disp20(rp)  */
    338 	      (disp20_opcod == 0x4FFF0019) ||	/* storb -disp20(reg) */
    339 	      (disp20_opcod == 0x5FFF0019) ||	/* storb -disp20(rp)  */
    340 	      (disp20_opcod == 0x8FFF0019) ||	/* stord -disp20(reg) */
    341 	      (disp20_opcod == 0x9FFF0019) ||	/* stord -disp20(rp)  */
    342 	      (disp20_opcod == 0xCFFF0019) ||	/* storw -disp20(reg) */
    343 	      (disp20_opcod == 0xDFFF0019))
    344 	    {	/* storw -disp20(rp).  */
    345 	      neg = 1;
    346 	      value |= 0xFFF00000;
    347 	    }
    348 
    349 	  break;
    350 	default:
    351 	  return bfd_reloc_notsupported;
    352 	}
    353       break;
    354 
    355     case R_16C_ABS:
    356       switch (size)
    357 	{
    358 	case R_S_16C_20:    /* word1(0-3),word2.  */
    359 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    360 	  left_val = value & 0x0000FFF0;
    361 	  value = ((value & 0xFFFF0000) >> 16) |
    362 	    ((value & 0x0000000F) << 16);
    363 	  break;
    364 	case R_S_16C_24:   /* word2(0-3,8-11),word3.  */
    365 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    366 	  left_val = value & 0x0000F0F0;
    367 	  value = ((value & 0xFFFF0000) >> 16) |
    368 	    ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
    369 	  break;
    370 	default:
    371 	  return bfd_reloc_notsupported;
    372 	}
    373       break;
    374 
    375     case R_16C_IMMED:
    376       switch (size)
    377 	{
    378 	case R_S_16C_04:    /* word1/2(4-7).  */
    379 	  value = bfd_get_8 (abfd, (char *) data + octets);
    380 	  left_val = value & 0xF;
    381 	  value = (value & 0xF0) >> 4;
    382 	  break;
    383 	case R_S_16C_16:    /* word2.  */
    384 	  sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
    385 	  value = sword;
    386 	  break;
    387 	case R_S_16C_20:    /* word1(0-3),word2.  */
    388 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    389 	  left_val = value & 0x0000FFF0;
    390 	  value = ((value & 0xFFFF0000) >> 16) |
    391 	    ((value & 0x0000000F) << 16);
    392 	  break;
    393 	case R_S_16C_32:    /* word2, word3.  */
    394 	  value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
    395 	  value = ((value & 0x0000FFFF) << 16) |
    396 	    ((value & 0xFFFF0000) >> 16);
    397 	  break;
    398 	default:
    399 	  return bfd_reloc_notsupported;
    400 	}
    401       break;
    402     default:
    403       return bfd_reloc_notsupported;
    404     }
    405 
    406   switch ((r_type & R_RELTO) >> 4)
    407     {
    408 
    409     case 0:	/* R_ABS.  */
    410       plus_factor = Rvalue;
    411       break;
    412     case 1:	/* R_PCREL.  */
    413       plus_factor = Rvalue -
    414 	(input_section->output_section->vma + input_section->output_offset);
    415       break;
    416     default:
    417       return bfd_reloc_notsupported;
    418     }
    419 
    420   if (neg)
    421     {
    422       if (plus_factor >= -value)
    423 	neg2pos = 1;
    424       /* We need to change load/stor with negative
    425 	 displ opcode to positive disp opcode (CR16C).  */
    426     }
    427 
    428   value = value + (plus_factor >> code_factor);
    429 
    430   switch (format)
    431     {
    432     case R_NUMBER:
    433       switch (size)
    434 	{
    435 	case R_S_16C_08: 	/* One byte.  */
    436 	  if (value > (int) MAX_UBYTE || value < MIN_BYTE)
    437 	    return bfd_reloc_overflow;
    438 	  value &= 0xFF;
    439 	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
    440 	  break;
    441 
    442 	case R_S_16C_16:	/* Two bytes.  */
    443 	  if (value > (int) MAX_UWORD || value < MIN_WORD)
    444 	    return bfd_reloc_overflow;
    445 	  value &= 0xFFFF;
    446 	  sword = value;
    447 	  bfd_put_16 (abfd, (bfd_vma) sword,
    448 		      (unsigned char *) data + octets);
    449 	  break;
    450 
    451 	case R_S_16C_32:	/* Four bytes.  */
    452 	  value &= 0xFFFFFFFF;
    453 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    454 	  break;
    455 
    456 	default:
    457 	  return bfd_reloc_notsupported;
    458 	}
    459       break;
    460 
    461     case R_16C_DISPL:
    462       switch (size)
    463 	{
    464 	case R_S_16C_04:	/* word1(4-7).  */
    465 	  if ((value - 32) > 32 || value < 2)
    466 	    return bfd_reloc_overflow;
    467 	  value >>= 1;
    468 	  value--;
    469 	  value &= 0xF;
    470 	  value <<= 4;
    471 	  value |= left_val;
    472 	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
    473 	  break;
    474 
    475 	case R_S_16C_08:    /* word1(0-3,8-11).  */
    476 	  if (value > 255 || value < -256 || value == 0x80)
    477 	    return bfd_reloc_overflow;
    478 	  value &= 0x1FF;
    479 	  value >>= 1;
    480 	  sword = value & 0x000F;
    481 	  sword |= (value & 0x00F0) << 4;
    482 	  sword |= left_val;
    483 	  bfd_put_16 (abfd, (bfd_vma) sword,
    484 		      (unsigned char *) data + octets);
    485 	  break;
    486 
    487 	case R_S_16C_16:    /* word2.  */
    488 	  if (value > 65535 || value < -65536)
    489 	    return bfd_reloc_overflow;
    490 	  value >>= 1;
    491 	  value &= 0xFFFF;
    492 	  value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1);
    493 	  sword = value;
    494 	  bfd_put_16 (abfd, (bfd_vma) sword,
    495 		      (unsigned char *) data + octets);
    496 	  break;
    497 
    498 	case R_S_16C_24_a:	/* word1(0-7),word2.  */
    499 	  if (value > 16777215 || value < -16777216)
    500 	    return bfd_reloc_overflow;
    501 	  value &= 0x1FFFFFF;
    502 	  value >>= 1;
    503 	  value = ((value & 0x00007FFF) << 17) |
    504 	    ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15);
    505 	  value |= left_val;
    506 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    507 	  break;
    508 
    509 	case R_S_16C_24:    /* word2(0-3,8-11),word3.  */
    510 	  if (value > 16777215 || value < -16777216)
    511 	    return bfd_reloc_overflow;
    512 	  value &= 0x1FFFFFF;
    513 	  value >>= 1;
    514 
    515 	  value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23);
    516 
    517 	  value = ((value & 0x0000FFFF) << 16) |
    518 	    ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
    519 	  value |= left_val;
    520 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    521 	  break;
    522 
    523 	default:
    524 	  return bfd_reloc_notsupported;
    525 	}
    526       break;
    527 
    528     case R_16C_REGREL:
    529       switch (size)
    530 	{
    531 	case R_S_16C_04:	/* word1(12-15) not scaled.  */
    532 	  if (value > 13 || value < 0)
    533 	    return bfd_reloc_overflow;
    534 	  value &= 0xF;
    535 	  value |= left_val;
    536 	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
    537 	  break;
    538 
    539 	case R_S_16C_04_a:	/* word1(12-15) not scaled.  */
    540 	  if (value > 26 || value < 0)
    541 	    return bfd_reloc_overflow;
    542 	  value &= 0x1F;
    543 	  value >>= 1;
    544 	  value |= left_val;
    545 	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
    546 	  break;
    547 
    548 	case R_S_16C_14:	/* word1(4-5),word2(0-3,8-15).  */
    549 	  if (value < 0 || value > 16383)
    550 	    return bfd_reloc_overflow;
    551 	  value &= 0x3FFF;
    552 	  value = ((value & 0x000000c0) << 24) |
    553 	    ((value & 0x00003F00) << 16) |
    554 	    ((value & 0x0000000F) << 16) | (value & 0x00000030);
    555 	  value |= left_val;
    556 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    557 	  break;
    558 
    559 	case R_S_16C_16:	/* word2.  */
    560 	  if (value > 65535 || value < 0)
    561 	    return bfd_reloc_overflow;
    562 	  value &= 0xFFFF;
    563 	  sword = value;
    564 	  bfd_put_16 (abfd, (bfd_vma) sword,
    565 		      (unsigned char *) data + octets);
    566 	  break;
    567 
    568 	case R_S_16C_20:	/* word2(8-11),word3.  */
    569 	  /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */
    570 	  value &= 0xFFFFF;
    571 	  sword = value & 0x0000FFFF;
    572 	  value = (value & 0x000F0000) >> 16;
    573 	  value |= left_val;
    574 	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
    575 	  bfd_put_16 (abfd, (bfd_vma) sword,
    576 		      (unsigned char *) data + octets + 1);
    577 	  if (neg2pos)
    578 	    {
    579 	      /* Change load/stor negative displ opcode
    580 	         to load/stor positive displ opcode.  */
    581 	      value = bfd_get_8 (abfd, (char *) data + octets - 3);
    582 	      value &= 0xF7;
    583 	      value |= 0x2;
    584 	      bfd_put_8 (abfd, (bfd_vma) value,
    585 			 (unsigned char *) data + octets - 3);
    586 	    }
    587 	  break;
    588 
    589 	default:
    590 	  return bfd_reloc_notsupported;
    591 	}
    592       break;
    593 
    594     case R_16C_ABS:
    595       switch (size)
    596 	{
    597 	case R_S_16C_20:	/* word1(0-3),word2.  */
    598 	  if (value > 1048575 || value < 0)
    599 	    return bfd_reloc_overflow;
    600 	  value &= 0xFFFFF;
    601 	  value = ((value & 0x0000FFFF) << 16) |
    602 	    ((value & 0x000F0000) >> 16);
    603 	  value |= left_val;
    604 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    605 	  break;
    606 
    607 	case R_S_16C_24:	/* word2(0-3,8-11),word3.  */
    608 	  /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */
    609 	  value &= 0xFFFFFF;
    610 	  value = ((value & 0x0000FFFF) << 16) |
    611 	    ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
    612 	  value |= left_val;
    613 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    614 	  break;
    615 
    616 	default:
    617 	  return bfd_reloc_notsupported;
    618 	}
    619       break;
    620 
    621     case R_16C_IMMED:
    622       switch (size)
    623 	{
    624 	case R_S_16C_04:	/* word1/2(4-7).  */
    625 	  if (value > 15 || value < -1)
    626 	    return bfd_reloc_overflow;
    627 	  value &= 0xF;
    628 	  value <<= 4;
    629 	  value |= left_val;
    630 	  bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
    631 	  break;
    632 
    633 	case R_S_16C_16:	/* word2.  */
    634 	  if (value > 32767 || value < -32768)
    635 	    return bfd_reloc_overflow;
    636 	  value &= 0xFFFF;
    637 	  sword = value;
    638 	  bfd_put_16 (abfd, (bfd_vma) sword,
    639 		      (unsigned char *) data + octets);
    640 	  break;
    641 
    642 	case R_S_16C_20:	/* word1(0-3),word2.  */
    643 	  if (value > 1048575 || value < 0)
    644 	    return bfd_reloc_overflow;
    645 	  value &= 0xFFFFF;
    646 	  value = ((value & 0x0000FFFF) << 16) |
    647 	    ((value & 0x000F0000) >> 16);
    648 	  value |= left_val;
    649 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    650 	  break;
    651 
    652 	case R_S_16C_32:	/* word2, word3.  */
    653 	  value &= 0xFFFFFFFF;
    654 	  value = ((value & 0x0000FFFF) << 16) |
    655 	    ((value & 0xFFFF0000) >> 16);
    656 	  bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
    657 	  break;
    658 
    659 	default:
    660 	  return bfd_reloc_notsupported;
    661 	}
    662       break;
    663     default:
    664       return bfd_reloc_notsupported;
    665     }
    666 
    667   return bfd_reloc_ok;
    668 }
    669 
    670 /* Relocate a CR16C ELF section.  */
    671 
    672 static bfd_boolean
    673 elf32_cr16c_relocate_section (bfd *output_bfd,
    674 			      struct bfd_link_info *info,
    675 			      bfd *input_bfd,
    676 			      asection *input_section,
    677 			      bfd_byte *contents,
    678 			      Elf_Internal_Rela *relocs,
    679 			      Elf_Internal_Sym *local_syms,
    680 			      asection **local_sections)
    681 {
    682   Elf_Internal_Shdr *symtab_hdr;
    683   struct elf_link_hash_entry **sym_hashes;
    684   Elf_Internal_Rela *rel, *relend;
    685 
    686   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    687   sym_hashes = elf_sym_hashes (input_bfd);
    688 
    689   rel = relocs;
    690   relend = relocs + input_section->reloc_count;
    691   for (; rel < relend; rel++)
    692     {
    693       int r_type;
    694       reloc_howto_type *howto;
    695       unsigned long r_symndx;
    696       Elf_Internal_Sym *sym;
    697       asection *sec;
    698       struct elf_link_hash_entry *h;
    699       bfd_vma relocation;
    700       bfd_reloc_status_type r;
    701 
    702       r_symndx = ELF32_R_SYM (rel->r_info);
    703       r_type = ELF32_R_TYPE (rel->r_info);
    704       howto = elf_howto_table + r_type;
    705 
    706       h = NULL;
    707       sym = NULL;
    708       sec = NULL;
    709       if (r_symndx < symtab_hdr->sh_info)
    710 	{
    711 	  sym = local_syms + r_symndx;
    712 	  sec = local_sections[r_symndx];
    713 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
    714 	}
    715       else
    716 	{
    717 	  bfd_boolean unresolved_reloc, warned, ignored;
    718 
    719 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    720 				   r_symndx, symtab_hdr, sym_hashes,
    721 				   h, sec, relocation,
    722 				   unresolved_reloc, warned, ignored);
    723 	}
    724 
    725       if (sec != NULL && discarded_section (sec))
    726 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    727 					 rel, 1, relend, howto, 0, contents);
    728 
    729       if (info->relocatable)
    730 	{
    731 	  /* This is a relocatable link.  We don't have to change
    732 	     anything, unless the reloc is against a section symbol,
    733 	     in which case we have to adjust according to where the
    734 	     section symbol winds up in the output section.  */
    735 	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
    736 	    rel->r_addend += sec->output_offset;
    737 	  continue;
    738 	}
    739 
    740       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
    741 					 input_section,
    742 					 contents, rel->r_offset,
    743 					 relocation, rel->r_addend,
    744 					 info, sec, h == NULL);
    745 
    746       if (r != bfd_reloc_ok)
    747 	{
    748 	  const char *name;
    749 	  const char *msg = (const char *) 0;
    750 
    751 	  if (h != NULL)
    752 	    name = h->root.root.string;
    753 	  else
    754 	    {
    755 	      name = (bfd_elf_string_from_elf_section
    756 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
    757 	      if (name == NULL || *name == '\0')
    758 		name = bfd_section_name (input_bfd, sec);
    759 	    }
    760 
    761 	  switch (r)
    762 	    {
    763 	    case bfd_reloc_overflow:
    764 	      if (!((*info->callbacks->reloc_overflow)
    765 		    (info, (h ? &h->root : NULL), name, howto->name,
    766 		     (bfd_vma) 0, input_bfd, input_section,
    767 		     rel->r_offset)))
    768 		return FALSE;
    769 	      break;
    770 
    771 	    case bfd_reloc_undefined:
    772 	      if (!((*info->callbacks->undefined_symbol)
    773 		    (info, name, input_bfd, input_section,
    774 		     rel->r_offset, TRUE)))
    775 		return FALSE;
    776 	      break;
    777 
    778 	    case bfd_reloc_outofrange:
    779 	      msg = _("internal error: out of range error");
    780 	      goto common_error;
    781 
    782 	    case bfd_reloc_notsupported:
    783 	      msg = _("internal error: unsupported relocation error");
    784 	      goto common_error;
    785 
    786 	    case bfd_reloc_dangerous:
    787 	      msg = _("internal error: dangerous error");
    788 	      goto common_error;
    789 
    790 	    default:
    791 	      msg = _("internal error: unknown error");
    792 	      /* fall through */
    793 
    794 	    common_error:
    795 	      if (!((*info->callbacks->warning)
    796 		    (info, msg, name, input_bfd, input_section,
    797 		     rel->r_offset)))
    798 		return FALSE;
    799 	      break;
    800 	    }
    801 	}
    802     }
    803 
    804   return TRUE;
    805 }
    806 
    807 /* CR16C ELF uses three common sections:
    808    One is for default common symbols (placed in usual common section).
    809    Second is for near common symbols (placed in "ncommon" section).
    810    Third is for far common symbols (placed in "fcommon" section).
    811    The following implementation is based on elf32-mips architecture */
    812 
    813 static asection  cr16c_elf_fcom_section;
    814 static asymbol   cr16c_elf_fcom_symbol;
    815 static asymbol * cr16c_elf_fcom_symbol_ptr;
    816 static asection  cr16c_elf_ncom_section;
    817 static asymbol   cr16c_elf_ncom_symbol;
    818 static asymbol * cr16c_elf_ncom_symbol_ptr;
    819 
    820 /* Given a BFD section, try to locate the
    821    corresponding ELF section index.  */
    822 
    823 static bfd_boolean
    824 elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
    825 				      asection *sec,
    826 				      int *retval)
    827 {
    828   if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
    829     *retval = SHN_CR16C_FCOMMON;
    830   else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
    831     *retval = SHN_CR16C_NCOMMON;
    832   else
    833     return FALSE;
    834 
    835   return TRUE;
    836 }
    837 
    838 /* Handle the special CR16C section numbers that a symbol may use.  */
    839 
    840 static void
    841 elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
    842 			       asymbol *asym)
    843 {
    844   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
    845   unsigned int indx;
    846 
    847   indx = elfsym->internal_elf_sym.st_shndx;
    848 
    849   switch (indx)
    850     {
    851     case SHN_CR16C_FCOMMON:
    852       if (cr16c_elf_fcom_section.name == NULL)
    853 	{
    854 	  /* Initialize the far common section.  */
    855 	  cr16c_elf_fcom_section.name = ".fcommon";
    856 	  cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
    857 	  cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
    858 	  cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
    859 	  cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
    860 	  cr16c_elf_fcom_symbol.name = ".fcommon";
    861 	  cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
    862 	  cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
    863 	  cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
    864 	}
    865       asym->section = &cr16c_elf_fcom_section;
    866       asym->value = elfsym->internal_elf_sym.st_size;
    867       break;
    868     case SHN_CR16C_NCOMMON:
    869       if (cr16c_elf_ncom_section.name == NULL)
    870 	{
    871 	  /* Initialize the far common section.  */
    872 	  cr16c_elf_ncom_section.name = ".ncommon";
    873 	  cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
    874 	  cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
    875 	  cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
    876 	  cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
    877 	  cr16c_elf_ncom_symbol.name = ".ncommon";
    878 	  cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
    879 	  cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
    880 	  cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
    881 	}
    882       asym->section = &cr16c_elf_ncom_section;
    883       asym->value = elfsym->internal_elf_sym.st_size;
    884       break;
    885     }
    886 }
    887 
    888 /* Hook called by the linker routine which adds symbols from an object
    889    file.  We must handle the special cr16c section numbers here.  */
    890 
    891 static bfd_boolean
    892 elf32_cr16c_add_symbol_hook (bfd *abfd,
    893 			     struct bfd_link_info *info ATTRIBUTE_UNUSED,
    894 			     Elf_Internal_Sym *sym,
    895 			     const char **namep ATTRIBUTE_UNUSED,
    896 			     flagword *flagsp ATTRIBUTE_UNUSED,
    897 			     asection **secp,
    898 			     bfd_vma *valp)
    899 {
    900   unsigned int indx = sym->st_shndx;
    901 
    902   switch (indx)
    903     {
    904     case SHN_CR16C_FCOMMON:
    905       *secp = bfd_make_section_old_way (abfd, ".fcommon");
    906       (*secp)->flags |= SEC_IS_COMMON;
    907       *valp = sym->st_size;
    908       break;
    909     case SHN_CR16C_NCOMMON:
    910       *secp = bfd_make_section_old_way (abfd, ".ncommon");
    911       (*secp)->flags |= SEC_IS_COMMON;
    912       *valp = sym->st_size;
    913       break;
    914     }
    915 
    916   return TRUE;
    917 }
    918 
    919 static int
    920 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
    921 				     const char *name ATTRIBUTE_UNUSED,
    922 				     Elf_Internal_Sym *sym,
    923 				     asection *input_sec,
    924 				     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
    925 {
    926   /* If we see a common symbol, which implies a relocatable link, then
    927      if a symbol was in a special common section in an input file, mark
    928      it as a special common in the output file.  */
    929 
    930   if (sym->st_shndx == SHN_COMMON)
    931     {
    932       if (strcmp (input_sec->name, ".fcommon") == 0)
    933 	sym->st_shndx = SHN_CR16C_FCOMMON;
    934       else if (strcmp (input_sec->name, ".ncommon") == 0)
    935 	sym->st_shndx = SHN_CR16C_NCOMMON;
    936     }
    937 
    938   return 1;
    939 }
    940 
    941 /* Definitions for setting CR16C target vector.  */
    942 #define TARGET_LITTLE_SYM		cr16c_elf32_vec
    943 #define TARGET_LITTLE_NAME		"elf32-cr16c"
    944 #define ELF_ARCH			bfd_arch_cr16c
    945 #define ELF_MACHINE_CODE		EM_CR
    946 #define ELF_MAXPAGESIZE			0x1
    947 #define elf_symbol_leading_char		'_'
    948 
    949 #define bfd_elf32_bfd_reloc_type_lookup		elf_cr16c_reloc_type_lookup
    950 #define bfd_elf32_bfd_reloc_name_lookup	elf_cr16c_reloc_name_lookup
    951 #define elf_info_to_howto			elf_cr16c_info_to_howto
    952 #define elf_info_to_howto_rel			elf_cr16c_info_to_howto_rel
    953 #define elf_backend_relocate_section		elf32_cr16c_relocate_section
    954 #define elf_backend_symbol_processing		elf32_cr16c_symbol_processing
    955 #define elf_backend_section_from_bfd_section 	elf32_cr16c_section_from_bfd_section
    956 #define elf_backend_add_symbol_hook		elf32_cr16c_add_symbol_hook
    957 #define elf_backend_link_output_symbol_hook 	elf32_cr16c_link_output_symbol_hook
    958 
    959 #define elf_backend_can_gc_sections     1
    960 
    961 #include "elf32-target.h"
    962