1/* BFD back-end for National Semiconductor's CR16C ELF 2 Copyright (C) 2004-2017 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 44RELOC_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 88static 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 135static reloc_howto_type * 136elf_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 154static reloc_howto_type * 155elf_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 168static void 169elf_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 176static void 177elf_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 if (r_type >= RINDEX_16C_MAX) 184 { 185 /* xgettext:c-format */ 186 _bfd_error_handler (_("%B: invalid CR16C reloc number: %d"), abfd, r_type); 187 r_type = 0; 188 } 189 cache_ptr->howto = &elf_howto_table[r_type]; 190} 191 192/* Perform a relocation as part of a final link. */ 193 194static bfd_reloc_status_type 195cr16c_elf_final_link_relocate (reloc_howto_type *howto, 196 bfd *abfd, 197 bfd *output_bfd ATTRIBUTE_UNUSED, 198 asection *input_section, 199 bfd_byte *data, 200 bfd_vma octets, 201 bfd_vma Rvalue, 202 bfd_vma addend ATTRIBUTE_UNUSED, 203 struct bfd_link_info *info ATTRIBUTE_UNUSED, 204 asection *sym_sec ATTRIBUTE_UNUSED, 205 int is_local ATTRIBUTE_UNUSED) 206{ 207 long value; 208 short sword; /* Extracted from the hole and put back. */ 209 unsigned long format, addr_type, code_factor; 210 unsigned short size; 211 unsigned short r_type; 212 213 unsigned long disp20_opcod; 214 char neg = 0; 215 char neg2pos = 0; 216 217 long left_val = 0; 218 long plus_factor = 0; /* To be added to the hole. */ 219 220#define MIN_BYTE ((int) 0xFFFFFF80) 221#define MIN_WORD ((int) 0xFFFF8000) 222#define MAX_UWORD ((unsigned) 0x0000FFFF) 223#define MAX_UBYTE ((unsigned) 0x000000FF) 224 225 r_type = reloc_map_index[howto->type].cr_reloc_type; 226 format = r_type & R_FORMAT; 227 size = r_type & R_SIZESP; 228 addr_type = r_type & R_ADDRTYPE; 229 code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0); 230 231 switch (format) 232 { 233 case R_NUMBER: 234 switch (size) 235 { 236 case R_S_16C_08: /* One byte. */ 237 value = bfd_get_8 (abfd, (char *) data + octets); 238 break; 239 case R_S_16C_16: /* Two bytes. */ 240 sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); 241 value = sword; 242 break; 243 case R_S_16C_32: /* Four bytes. */ 244 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 245 break; 246 default: 247 return bfd_reloc_notsupported; 248 } 249 break; 250 251 case R_16C_DISPL: 252 switch (size) 253 { 254 case R_S_16C_04: /* word1(4-7). */ 255 value = bfd_get_8 (abfd, (char *) data + octets); 256 left_val = value & 0xF; 257 value = (value & 0xF0) >> 4; 258 value++; 259 value <<= 1; 260 break; 261 case R_S_16C_08: /* word1(0-3,8-11). */ 262 sword = bfd_get_16 (abfd, (char *) data + octets); 263 value = sword & 0x000F; 264 value |= ((sword & 0x0F00) >> 4); 265 left_val = sword & 0xF0F0; 266 value <<= 1; 267 if (value & 0x100) 268 value |= 0xFFFFFF00; 269 break; 270 case R_S_16C_16: /* word2. */ 271 sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); 272 value = sword; 273 value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15); 274 value <<= 1; 275 if (value & 0x10000) 276 value |= 0xFFFF0000; 277 break; 278 case R_S_16C_24_a: /* word1(0-7),word2. */ 279 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 280 left_val = value & 0x0000FF00; 281 value = ((value & 0xFFFE0000) >> 17) | 282 ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15); 283 value <<= 1; 284 if (value & 0x1000000) 285 value |= 0xFE000000; 286 break; 287 case R_S_16C_24: /* word2(0-3,8-11),word3. */ 288 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 289 left_val = value & 0x0000F0F0; 290 value = ((value >> 16) & 0x0000FFFF) | 291 ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20); 292 293 value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23); 294 295 value <<= 1; 296 if (value & 0x1000000) 297 value |= 0xFE000000; 298 break; 299 default: 300 return bfd_reloc_notsupported; 301 } 302 break; 303 304 case R_16C_REGREL: 305 switch (size) 306 { 307 case R_S_16C_04: /* word1(12-15) not scaled. */ 308 value = bfd_get_8 (abfd, (char *) data + octets); 309 left_val = value & 0xF0; 310 value = value & 0xF; 311 break; 312 case R_S_16C_04_a: /* word1(12-15) scaled by 2. */ 313 value = bfd_get_8 (abfd, (char *) data + octets); 314 left_val = value & 0xF0; 315 value = value & 0xF; 316 value <<= 1; 317 break; 318 case R_S_16C_14: /* word1(4-5),word2(0-3,8-15). */ 319 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 320 left_val = value & 0x00F0FFCF; 321 value = ((value & 0xc0000000) >> 24) | 322 ((value & 0x3F000000) >> 16) | 323 ((value & 0x000F0000) >> 16) | (value & 0x00000030); 324 break; 325 case R_S_16C_16: /* word2. */ 326 sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); 327 value = sword; 328 break; 329 case R_S_16C_20: /* word2(8-11),word3. */ 330 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 331 left_val = value & 0xF0; 332 value = (value & 0xF) << 16; 333 sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1); 334 value = value | (unsigned short) sword; 335 disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3); 336 disp20_opcod |= 0x0FFF0000; 337 if ((disp20_opcod == 0x4FFF0018) || /* loadb -disp20(reg) */ 338 (disp20_opcod == 0x5FFF0018) || /* loadb -disp20(rp) */ 339 (disp20_opcod == 0x8FFF0018) || /* loadd -disp20(reg) */ 340 (disp20_opcod == 0x9FFF0018) || /* loadd -disp20(rp) */ 341 (disp20_opcod == 0xCFFF0018) || /* loadw -disp20(reg) */ 342 (disp20_opcod == 0xDFFF0018) || /* loadw -disp20(rp) */ 343 (disp20_opcod == 0x4FFF0019) || /* storb -disp20(reg) */ 344 (disp20_opcod == 0x5FFF0019) || /* storb -disp20(rp) */ 345 (disp20_opcod == 0x8FFF0019) || /* stord -disp20(reg) */ 346 (disp20_opcod == 0x9FFF0019) || /* stord -disp20(rp) */ 347 (disp20_opcod == 0xCFFF0019) || /* storw -disp20(reg) */ 348 (disp20_opcod == 0xDFFF0019)) 349 { /* storw -disp20(rp). */ 350 neg = 1; 351 value |= 0xFFF00000; 352 } 353 354 break; 355 default: 356 return bfd_reloc_notsupported; 357 } 358 break; 359 360 case R_16C_ABS: 361 switch (size) 362 { 363 case R_S_16C_20: /* word1(0-3),word2. */ 364 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 365 left_val = value & 0x0000FFF0; 366 value = ((value & 0xFFFF0000) >> 16) | 367 ((value & 0x0000000F) << 16); 368 break; 369 case R_S_16C_24: /* word2(0-3,8-11),word3. */ 370 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 371 left_val = value & 0x0000F0F0; 372 value = ((value & 0xFFFF0000) >> 16) | 373 ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20); 374 break; 375 default: 376 return bfd_reloc_notsupported; 377 } 378 break; 379 380 case R_16C_IMMED: 381 switch (size) 382 { 383 case R_S_16C_04: /* word1/2(4-7). */ 384 value = bfd_get_8 (abfd, (char *) data + octets); 385 left_val = value & 0xF; 386 value = (value & 0xF0) >> 4; 387 break; 388 case R_S_16C_16: /* word2. */ 389 sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); 390 value = sword; 391 break; 392 case R_S_16C_20: /* word1(0-3),word2. */ 393 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 394 left_val = value & 0x0000FFF0; 395 value = ((value & 0xFFFF0000) >> 16) | 396 ((value & 0x0000000F) << 16); 397 break; 398 case R_S_16C_32: /* word2, word3. */ 399 value = bfd_get_32 (abfd, (bfd_byte *) data + octets); 400 value = ((value & 0x0000FFFF) << 16) | 401 ((value & 0xFFFF0000) >> 16); 402 break; 403 default: 404 return bfd_reloc_notsupported; 405 } 406 break; 407 default: 408 return bfd_reloc_notsupported; 409 } 410 411 switch ((r_type & R_RELTO) >> 4) 412 { 413 414 case 0: /* R_ABS. */ 415 plus_factor = Rvalue; 416 break; 417 case 1: /* R_PCREL. */ 418 plus_factor = Rvalue - 419 (input_section->output_section->vma + input_section->output_offset); 420 break; 421 default: 422 return bfd_reloc_notsupported; 423 } 424 425 if (neg) 426 { 427 if (plus_factor >= -value) 428 neg2pos = 1; 429 /* We need to change load/stor with negative 430 displ opcode to positive disp opcode (CR16C). */ 431 } 432 433 value = value + (plus_factor >> code_factor); 434 435 switch (format) 436 { 437 case R_NUMBER: 438 switch (size) 439 { 440 case R_S_16C_08: /* One byte. */ 441 if (value > (int) MAX_UBYTE || value < MIN_BYTE) 442 return bfd_reloc_overflow; 443 value &= 0xFF; 444 bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); 445 break; 446 447 case R_S_16C_16: /* Two bytes. */ 448 if (value > (int) MAX_UWORD || value < MIN_WORD) 449 return bfd_reloc_overflow; 450 value &= 0xFFFF; 451 sword = value; 452 bfd_put_16 (abfd, (bfd_vma) sword, 453 (unsigned char *) data + octets); 454 break; 455 456 case R_S_16C_32: /* Four bytes. */ 457 value &= 0xFFFFFFFF; 458 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 459 break; 460 461 default: 462 return bfd_reloc_notsupported; 463 } 464 break; 465 466 case R_16C_DISPL: 467 switch (size) 468 { 469 case R_S_16C_04: /* word1(4-7). */ 470 if ((value - 32) > 32 || value < 2) 471 return bfd_reloc_overflow; 472 value >>= 1; 473 value--; 474 value &= 0xF; 475 value <<= 4; 476 value |= left_val; 477 bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); 478 break; 479 480 case R_S_16C_08: /* word1(0-3,8-11). */ 481 if (value > 255 || value < -256 || value == 0x80) 482 return bfd_reloc_overflow; 483 value &= 0x1FF; 484 value >>= 1; 485 sword = value & 0x000F; 486 sword |= (value & 0x00F0) << 4; 487 sword |= left_val; 488 bfd_put_16 (abfd, (bfd_vma) sword, 489 (unsigned char *) data + octets); 490 break; 491 492 case R_S_16C_16: /* word2. */ 493 if (value > 65535 || value < -65536) 494 return bfd_reloc_overflow; 495 value >>= 1; 496 value &= 0xFFFF; 497 value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1); 498 sword = value; 499 bfd_put_16 (abfd, (bfd_vma) sword, 500 (unsigned char *) data + octets); 501 break; 502 503 case R_S_16C_24_a: /* word1(0-7),word2. */ 504 if (value > 16777215 || value < -16777216) 505 return bfd_reloc_overflow; 506 value &= 0x1FFFFFF; 507 value >>= 1; 508 value = ((value & 0x00007FFF) << 17) | 509 ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15); 510 value |= left_val; 511 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 512 break; 513 514 case R_S_16C_24: /* word2(0-3,8-11),word3. */ 515 if (value > 16777215 || value < -16777216) 516 return bfd_reloc_overflow; 517 value &= 0x1FFFFFF; 518 value >>= 1; 519 520 value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23); 521 522 value = ((value & 0x0000FFFF) << 16) | 523 ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20); 524 value |= left_val; 525 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 526 break; 527 528 default: 529 return bfd_reloc_notsupported; 530 } 531 break; 532 533 case R_16C_REGREL: 534 switch (size) 535 { 536 case R_S_16C_04: /* word1(12-15) not scaled. */ 537 if (value > 13 || value < 0) 538 return bfd_reloc_overflow; 539 value &= 0xF; 540 value |= left_val; 541 bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); 542 break; 543 544 case R_S_16C_04_a: /* word1(12-15) not scaled. */ 545 if (value > 26 || value < 0) 546 return bfd_reloc_overflow; 547 value &= 0x1F; 548 value >>= 1; 549 value |= left_val; 550 bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); 551 break; 552 553 case R_S_16C_14: /* word1(4-5),word2(0-3,8-15). */ 554 if (value < 0 || value > 16383) 555 return bfd_reloc_overflow; 556 value &= 0x3FFF; 557 value = ((value & 0x000000c0) << 24) | 558 ((value & 0x00003F00) << 16) | 559 ((value & 0x0000000F) << 16) | (value & 0x00000030); 560 value |= left_val; 561 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 562 break; 563 564 case R_S_16C_16: /* word2. */ 565 if (value > 65535 || value < 0) 566 return bfd_reloc_overflow; 567 value &= 0xFFFF; 568 sword = value; 569 bfd_put_16 (abfd, (bfd_vma) sword, 570 (unsigned char *) data + octets); 571 break; 572 573 case R_S_16C_20: /* word2(8-11),word3. */ 574 /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */ 575 value &= 0xFFFFF; 576 sword = value & 0x0000FFFF; 577 value = (value & 0x000F0000) >> 16; 578 value |= left_val; 579 bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); 580 bfd_put_16 (abfd, (bfd_vma) sword, 581 (unsigned char *) data + octets + 1); 582 if (neg2pos) 583 { 584 /* Change load/stor negative displ opcode 585 to load/stor positive displ opcode. */ 586 value = bfd_get_8 (abfd, (char *) data + octets - 3); 587 value &= 0xF7; 588 value |= 0x2; 589 bfd_put_8 (abfd, (bfd_vma) value, 590 (unsigned char *) data + octets - 3); 591 } 592 break; 593 594 default: 595 return bfd_reloc_notsupported; 596 } 597 break; 598 599 case R_16C_ABS: 600 switch (size) 601 { 602 case R_S_16C_20: /* word1(0-3),word2. */ 603 if (value > 1048575 || value < 0) 604 return bfd_reloc_overflow; 605 value &= 0xFFFFF; 606 value = ((value & 0x0000FFFF) << 16) | 607 ((value & 0x000F0000) >> 16); 608 value |= left_val; 609 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 610 break; 611 612 case R_S_16C_24: /* word2(0-3,8-11),word3. */ 613 /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */ 614 value &= 0xFFFFFF; 615 value = ((value & 0x0000FFFF) << 16) | 616 ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20); 617 value |= left_val; 618 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 619 break; 620 621 default: 622 return bfd_reloc_notsupported; 623 } 624 break; 625 626 case R_16C_IMMED: 627 switch (size) 628 { 629 case R_S_16C_04: /* word1/2(4-7). */ 630 if (value > 15 || value < -1) 631 return bfd_reloc_overflow; 632 value &= 0xF; 633 value <<= 4; 634 value |= left_val; 635 bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); 636 break; 637 638 case R_S_16C_16: /* word2. */ 639 if (value > 32767 || value < -32768) 640 return bfd_reloc_overflow; 641 value &= 0xFFFF; 642 sword = value; 643 bfd_put_16 (abfd, (bfd_vma) sword, 644 (unsigned char *) data + octets); 645 break; 646 647 case R_S_16C_20: /* word1(0-3),word2. */ 648 if (value > 1048575 || value < 0) 649 return bfd_reloc_overflow; 650 value &= 0xFFFFF; 651 value = ((value & 0x0000FFFF) << 16) | 652 ((value & 0x000F0000) >> 16); 653 value |= left_val; 654 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 655 break; 656 657 case R_S_16C_32: /* word2, word3. */ 658 value &= 0xFFFFFFFF; 659 value = ((value & 0x0000FFFF) << 16) | 660 ((value & 0xFFFF0000) >> 16); 661 bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); 662 break; 663 664 default: 665 return bfd_reloc_notsupported; 666 } 667 break; 668 default: 669 return bfd_reloc_notsupported; 670 } 671 672 return bfd_reloc_ok; 673} 674 675/* Relocate a CR16C ELF section. */ 676 677static bfd_boolean 678elf32_cr16c_relocate_section (bfd *output_bfd, 679 struct bfd_link_info *info, 680 bfd *input_bfd, 681 asection *input_section, 682 bfd_byte *contents, 683 Elf_Internal_Rela *relocs, 684 Elf_Internal_Sym *local_syms, 685 asection **local_sections) 686{ 687 Elf_Internal_Shdr *symtab_hdr; 688 struct elf_link_hash_entry **sym_hashes; 689 Elf_Internal_Rela *rel, *relend; 690 691 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 692 sym_hashes = elf_sym_hashes (input_bfd); 693 694 rel = relocs; 695 relend = relocs + input_section->reloc_count; 696 for (; rel < relend; rel++) 697 { 698 int r_type; 699 reloc_howto_type *howto; 700 unsigned long r_symndx; 701 Elf_Internal_Sym *sym; 702 asection *sec; 703 struct elf_link_hash_entry *h; 704 bfd_vma relocation; 705 bfd_reloc_status_type r; 706 707 r_symndx = ELF32_R_SYM (rel->r_info); 708 r_type = ELF32_R_TYPE (rel->r_info); 709 howto = elf_howto_table + r_type; 710 711 h = NULL; 712 sym = NULL; 713 sec = NULL; 714 if (r_symndx < symtab_hdr->sh_info) 715 { 716 sym = local_syms + r_symndx; 717 sec = local_sections[r_symndx]; 718 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 719 } 720 else 721 { 722 bfd_boolean unresolved_reloc, warned, ignored; 723 724 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 725 r_symndx, symtab_hdr, sym_hashes, 726 h, sec, relocation, 727 unresolved_reloc, warned, ignored); 728 } 729 730 if (sec != NULL && discarded_section (sec)) 731 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 732 rel, 1, relend, howto, 0, contents); 733 734 if (bfd_link_relocatable (info)) 735 { 736 /* This is a relocatable link. We don't have to change 737 anything, unless the reloc is against a section symbol, 738 in which case we have to adjust according to where the 739 section symbol winds up in the output section. */ 740 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) 741 rel->r_addend += sec->output_offset; 742 continue; 743 } 744 745 r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd, 746 input_section, 747 contents, rel->r_offset, 748 relocation, rel->r_addend, 749 info, sec, h == NULL); 750 751 if (r != bfd_reloc_ok) 752 { 753 const char *name; 754 const char *msg = (const char *) 0; 755 756 if (h != NULL) 757 name = h->root.root.string; 758 else 759 { 760 name = (bfd_elf_string_from_elf_section 761 (input_bfd, symtab_hdr->sh_link, sym->st_name)); 762 if (name == NULL || *name == '\0') 763 name = bfd_section_name (input_bfd, sec); 764 } 765 766 switch (r) 767 { 768 case bfd_reloc_overflow: 769 (*info->callbacks->reloc_overflow) 770 (info, (h ? &h->root : NULL), name, howto->name, 771 (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 772 break; 773 774 case bfd_reloc_undefined: 775 (*info->callbacks->undefined_symbol) 776 (info, name, input_bfd, input_section, rel->r_offset, TRUE); 777 break; 778 779 case bfd_reloc_outofrange: 780 msg = _("internal error: out of range error"); 781 goto common_error; 782 783 case bfd_reloc_notsupported: 784 msg = _("internal error: unsupported relocation error"); 785 goto common_error; 786 787 case bfd_reloc_dangerous: 788 msg = _("internal error: dangerous error"); 789 goto common_error; 790 791 default: 792 msg = _("internal error: unknown error"); 793 /* fall through */ 794 795 common_error: 796 (*info->callbacks->warning) (info, msg, name, input_bfd, 797 input_section, rel->r_offset); 798 break; 799 } 800 } 801 } 802 803 return TRUE; 804} 805 806/* CR16C ELF uses three common sections: 807 One is for default common symbols (placed in usual common section). 808 Second is for near common symbols (placed in "ncommon" section). 809 Third is for far common symbols (placed in "fcommon" section). 810 The following implementation is based on elf32-mips architecture */ 811 812static asection cr16c_elf_fcom_section; 813static asymbol cr16c_elf_fcom_symbol; 814static asymbol * cr16c_elf_fcom_symbol_ptr; 815static asection cr16c_elf_ncom_section; 816static asymbol cr16c_elf_ncom_symbol; 817static asymbol * cr16c_elf_ncom_symbol_ptr; 818 819/* Given a BFD section, try to locate the 820 corresponding ELF section index. */ 821 822static bfd_boolean 823elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, 824 asection *sec, 825 int *retval) 826{ 827 if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0) 828 *retval = SHN_CR16C_FCOMMON; 829 else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0) 830 *retval = SHN_CR16C_NCOMMON; 831 else 832 return FALSE; 833 834 return TRUE; 835} 836 837/* Handle the special CR16C section numbers that a symbol may use. */ 838 839static void 840elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, 841 asymbol *asym) 842{ 843 elf_symbol_type *elfsym = (elf_symbol_type *) asym; 844 unsigned int indx; 845 846 indx = elfsym->internal_elf_sym.st_shndx; 847 848 switch (indx) 849 { 850 case SHN_CR16C_FCOMMON: 851 if (cr16c_elf_fcom_section.name == NULL) 852 { 853 /* Initialize the far common section. */ 854 cr16c_elf_fcom_section.name = ".fcommon"; 855 cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC; 856 cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section; 857 cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol; 858 cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr; 859 cr16c_elf_fcom_symbol.name = ".fcommon"; 860 cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM; 861 cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section; 862 cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol; 863 } 864 asym->section = &cr16c_elf_fcom_section; 865 asym->value = elfsym->internal_elf_sym.st_size; 866 break; 867 case SHN_CR16C_NCOMMON: 868 if (cr16c_elf_ncom_section.name == NULL) 869 { 870 /* Initialize the far common section. */ 871 cr16c_elf_ncom_section.name = ".ncommon"; 872 cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC; 873 cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section; 874 cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol; 875 cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr; 876 cr16c_elf_ncom_symbol.name = ".ncommon"; 877 cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM; 878 cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section; 879 cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol; 880 } 881 asym->section = &cr16c_elf_ncom_section; 882 asym->value = elfsym->internal_elf_sym.st_size; 883 break; 884 } 885} 886 887/* Hook called by the linker routine which adds symbols from an object 888 file. We must handle the special cr16c section numbers here. */ 889 890static bfd_boolean 891elf32_cr16c_add_symbol_hook (bfd *abfd, 892 struct bfd_link_info *info ATTRIBUTE_UNUSED, 893 Elf_Internal_Sym *sym, 894 const char **namep ATTRIBUTE_UNUSED, 895 flagword *flagsp ATTRIBUTE_UNUSED, 896 asection **secp, 897 bfd_vma *valp) 898{ 899 unsigned int indx = sym->st_shndx; 900 901 switch (indx) 902 { 903 case SHN_CR16C_FCOMMON: 904 *secp = bfd_make_section_old_way (abfd, ".fcommon"); 905 (*secp)->flags |= SEC_IS_COMMON; 906 *valp = sym->st_size; 907 break; 908 case SHN_CR16C_NCOMMON: 909 *secp = bfd_make_section_old_way (abfd, ".ncommon"); 910 (*secp)->flags |= SEC_IS_COMMON; 911 *valp = sym->st_size; 912 break; 913 } 914 915 return TRUE; 916} 917 918static int 919elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, 920 const char *name ATTRIBUTE_UNUSED, 921 Elf_Internal_Sym *sym, 922 asection *input_sec, 923 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) 924{ 925 /* If we see a common symbol, which implies a relocatable link, then 926 if a symbol was in a special common section in an input file, mark 927 it as a special common in the output file. */ 928 929 if (sym->st_shndx == SHN_COMMON) 930 { 931 if (strcmp (input_sec->name, ".fcommon") == 0) 932 sym->st_shndx = SHN_CR16C_FCOMMON; 933 else if (strcmp (input_sec->name, ".ncommon") == 0) 934 sym->st_shndx = SHN_CR16C_NCOMMON; 935 } 936 937 return 1; 938} 939 940/* Definitions for setting CR16C target vector. */ 941#define TARGET_LITTLE_SYM cr16c_elf32_vec 942#define TARGET_LITTLE_NAME "elf32-cr16c" 943#define ELF_ARCH bfd_arch_cr16c 944#define ELF_MACHINE_CODE EM_CR 945#define ELF_MAXPAGESIZE 0x1 946#define elf_symbol_leading_char '_' 947 948#define bfd_elf32_bfd_reloc_type_lookup elf_cr16c_reloc_type_lookup 949#define bfd_elf32_bfd_reloc_name_lookup elf_cr16c_reloc_name_lookup 950#define elf_info_to_howto elf_cr16c_info_to_howto 951#define elf_info_to_howto_rel elf_cr16c_info_to_howto_rel 952#define elf_backend_relocate_section elf32_cr16c_relocate_section 953#define elf_backend_symbol_processing elf32_cr16c_symbol_processing 954#define elf_backend_section_from_bfd_section elf32_cr16c_section_from_bfd_section 955#define elf_backend_add_symbol_hook elf32_cr16c_add_symbol_hook 956#define elf_backend_link_output_symbol_hook elf32_cr16c_link_output_symbol_hook 957 958#define elf_backend_can_gc_sections 1 959 960#include "elf32-target.h" 961