1 /* Zilog (e)Z80-specific support for 32-bit ELF 2 Copyright (C) 1999-2019 Free Software Foundation, Inc. 3 (Heavily copied from the S12Z port by Sergey Belyashov (sergey.belyashov@gmail.com)) 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 28 #include "elf/z80.h" 29 30 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ 31 #define OCTETS_PER_BYTE(ABFD, SEC) 1 32 33 typedef struct { 34 bfd_reloc_code_real_type r_type; 35 reloc_howto_type howto; 36 } bfd_howto_type; 37 38 #define BFD_EMPTY_HOWTO(rt,x) {rt, EMPTY_HOWTO(x)} 39 #define BFD_HOWTO(rt,a,b,c,d,e,f,g,h,i,j,k,l,m) {rt, HOWTO(a,b,c,d,e,f,g,h,i,j,k,l,m)} 40 41 static bfd_reloc_status_type 42 z80_elf_16_be_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 43 void *data, asection *input_section, bfd *output_bfd, 44 char **error_message); 45 46 static const 47 bfd_howto_type elf_z80_howto_table[] = 48 { 49 /* This reloc does nothing. */ 50 BFD_HOWTO (BFD_RELOC_NONE, 51 R_Z80_NONE, /* type */ 52 0, /* rightshift */ 53 3, /* size (0 = byte, 1 = short, 2 = long) */ 54 0, /* bitsize */ 55 FALSE, /* pc_relative */ 56 0, /* bitpos */ 57 complain_overflow_dont,/* complain_on_overflow */ 58 bfd_elf_generic_reloc, /* special_function */ 59 "R_NONE", /* name */ 60 FALSE, /* partial_inplace */ 61 0, /* src_mask */ 62 0, /* dst_mask */ 63 FALSE), /* pcrel_offset */ 64 65 /* A 8 bit relocation */ 66 BFD_HOWTO (BFD_RELOC_8, 67 R_Z80_8, /* type */ 68 0, /* rightshift */ 69 0, /* size (0 = byte, 1 = short, 2 = long) */ 70 8, /* bitsize */ 71 FALSE, /* pc_relative */ 72 0, /* bitpos */ 73 complain_overflow_bitfield, /* complain_on_overflow */ 74 bfd_elf_generic_reloc, /* special_function */ 75 "r_imm8", /* name */ 76 FALSE, /* partial_inplace */ 77 0x00, /* src_mask */ 78 0xff, /* dst_mask */ 79 FALSE), /* pcrel_offset */ 80 81 /* A 8 bit index register displacement relocation */ 82 BFD_HOWTO (BFD_RELOC_Z80_DISP8, 83 R_Z80_8_DIS, /* type */ 84 0, /* rightshift */ 85 0, /* size (0 = byte, 1 = short, 2 = long) */ 86 8, /* bitsize */ 87 FALSE, /* pc_relative */ 88 0, /* bitpos */ 89 complain_overflow_signed, /* complain_on_overflow */ 90 bfd_elf_generic_reloc, /* special_function */ 91 "r_off", /* name */ 92 FALSE, /* partial_inplace */ 93 0x00, /* src_mask */ 94 0xff, /* dst_mask */ 95 FALSE), /* pcrel_offset */ 96 97 /* A 8 bit PC-rel relocation */ 98 BFD_HOWTO (BFD_RELOC_8_PCREL, 99 R_Z80_8_PCREL, /* type */ 100 0, /* rightshift */ 101 0, /* size (0 = byte, 1 = short, 2 = long) */ 102 8, /* bitsize */ 103 TRUE, /* pc_relative */ 104 0, /* bitpos */ 105 complain_overflow_signed, /* complain_on_overflow */ 106 bfd_elf_generic_reloc, /* special_function */ 107 "r_jr", /* name */ 108 FALSE, /* partial_inplace */ 109 0x00, /* src_mask */ 110 0xff, /* dst_mask */ 111 TRUE), /* pcrel_offset */ 112 113 /* An 16 bit absolute relocation */ 114 BFD_HOWTO (BFD_RELOC_16, 115 R_Z80_16, /* type */ 116 0, /* rightshift */ 117 1, /* size (0 = byte, 1 = short, 2 = long) */ 118 16, /* bitsize */ 119 FALSE, /* pc_relative */ 120 0, /* bitpos */ 121 complain_overflow_bitfield, /* complain_on_overflow */ 122 bfd_elf_generic_reloc, /* special_function */ 123 "r_imm16", /* name */ 124 FALSE, /* partial_inplace */ 125 0x00000000, /* src_mask */ 126 0x0000ffff, /* dst_mask */ 127 FALSE), /* pcrel_offset */ 128 129 /* A 24 bit absolute relocation emitted by ADL mode operands */ 130 BFD_HOWTO (BFD_RELOC_24, 131 R_Z80_24, /* type */ 132 0, /* rightshift */ 133 5, /* size (0 = byte, 1 = short, 2 = long) */ 134 24, /* bitsize */ 135 FALSE, /* pc_relative */ 136 0, /* bitpos */ 137 complain_overflow_bitfield, /* complain_on_overflow */ 138 bfd_elf_generic_reloc, /* special_function */ 139 "r_imm24", /* name */ 140 FALSE, /* partial_inplace */ 141 0x00000000, /* src_mask */ 142 0x00ffffff, /* dst_mask */ 143 FALSE), /* pcrel_offset */ 144 145 BFD_HOWTO (BFD_RELOC_32, 146 R_Z80_32, /* type */ 147 0, /* rightshift */ 148 2, /* size (0 = byte, 1 = short, 2 = long) */ 149 32, /* bitsize */ 150 FALSE, /* pc_relative */ 151 0, /* bitpos */ 152 complain_overflow_dont,/* complain_on_overflow */ 153 bfd_elf_generic_reloc, /* special_function */ 154 "r_imm32", /* name */ 155 FALSE, /* partial_inplace */ 156 0x00000000, /* src_mask */ 157 0xffffffff, /* dst_mask */ 158 FALSE), /* pcrel_offset */ 159 160 /* First (lowest) 8 bits of multibyte relocation */ 161 BFD_HOWTO (BFD_RELOC_Z80_BYTE0, 162 R_Z80_BYTE0, /* type */ 163 0, /* rightshift */ 164 0, /* size (0 = byte, 1 = short, 2 = long) */ 165 32, /* bitsize */ 166 FALSE, /* pc_relative */ 167 0, /* bitpos */ 168 complain_overflow_dont,/* complain_on_overflow */ 169 bfd_elf_generic_reloc, /* special_function */ 170 "r_byte0", /* name */ 171 FALSE, /* partial_inplace */ 172 0, /* src_mask */ 173 0xff, /* dst_mask */ 174 FALSE), /* pcrel_offset */ 175 176 /* Second 8 bits of multibyte relocation */ 177 BFD_HOWTO (BFD_RELOC_Z80_BYTE1, 178 R_Z80_BYTE1, /* type */ 179 8, /* rightshift */ 180 0, /* size (0 = byte, 1 = short, 2 = long) */ 181 32, /* bitsize */ 182 FALSE, /* pc_relative */ 183 0, /* bitpos */ 184 complain_overflow_dont,/* complain_on_overflow */ 185 bfd_elf_generic_reloc, /* special_function */ 186 "r_byte1", /* name */ 187 FALSE, /* partial_inplace */ 188 0, /* src_mask */ 189 0xff, /* dst_mask */ 190 FALSE), /* pcrel_offset */ 191 192 /* Third 8 bits of multibyte relocation */ 193 BFD_HOWTO (BFD_RELOC_Z80_BYTE2, 194 R_Z80_BYTE2, /* type */ 195 16, /* rightshift */ 196 0, /* size (0 = byte, 1 = short, 2 = long) */ 197 32, /* bitsize */ 198 FALSE, /* pc_relative */ 199 0, /* bitpos */ 200 complain_overflow_dont,/* complain_on_overflow */ 201 bfd_elf_generic_reloc, /* special_function */ 202 "r_byte2", /* name */ 203 FALSE, /* partial_inplace */ 204 0, /* src_mask */ 205 0xff, /* dst_mask */ 206 FALSE), /* pcrel_offset */ 207 208 /* Fourth (highest) 8 bits of multibyte relocation */ 209 BFD_HOWTO (BFD_RELOC_Z80_BYTE3, 210 R_Z80_BYTE3, /* type */ 211 24, /* rightshift */ 212 0, /* size (0 = byte, 1 = short, 2 = long) */ 213 32, /* bitsize */ 214 FALSE, /* pc_relative */ 215 0, /* bitpos */ 216 complain_overflow_dont,/* complain_on_overflow */ 217 bfd_elf_generic_reloc, /* special_function */ 218 "r_byte3", /* name */ 219 FALSE, /* partial_inplace */ 220 0, /* src_mask */ 221 0xff, /* dst_mask */ 222 FALSE), /* pcrel_offset */ 223 224 /* An 16 bit absolute relocation of lower word of multibyte value */ 225 BFD_HOWTO (BFD_RELOC_Z80_WORD0, 226 R_Z80_WORD0, /* type */ 227 0, /* rightshift */ 228 1, /* size (0 = byte, 1 = short, 2 = long) */ 229 32, /* bitsize */ 230 FALSE, /* pc_relative */ 231 0, /* bitpos */ 232 complain_overflow_dont,/* complain_on_overflow */ 233 bfd_elf_generic_reloc, /* special_function */ 234 "r_word0", /* name */ 235 FALSE, /* partial_inplace */ 236 0, /* src_mask */ 237 0xffff, /* dst_mask */ 238 FALSE), /* pcrel_offset */ 239 240 /* An 16 bit absolute relocation of higher word of multibyte value */ 241 BFD_HOWTO (BFD_RELOC_Z80_WORD1, 242 R_Z80_WORD1, /* type */ 243 16, /* rightshift */ 244 1, /* size (0 = byte, 1 = short, 2 = long) */ 245 32, /* bitsize */ 246 FALSE, /* pc_relative */ 247 0, /* bitpos */ 248 complain_overflow_dont,/* complain_on_overflow */ 249 bfd_elf_generic_reloc, /* special_function */ 250 "r_word1", /* name */ 251 FALSE, /* partial_inplace */ 252 0, /* src_mask */ 253 0xffff, /* dst_mask */ 254 FALSE), /* pcrel_offset */ 255 256 /* An 16 bit big endian absolute relocation */ 257 BFD_HOWTO (BFD_RELOC_Z80_16_BE, 258 R_Z80_16_BE, /* type */ 259 0, /* rightshift */ 260 1, /* size (0 = byte, 1 = short, 2 = long) */ 261 16, /* bitsize */ 262 FALSE, /* pc_relative */ 263 0, /* bitpos */ 264 complain_overflow_bitfield, /* complain_on_overflow */ 265 z80_elf_16_be_reloc, /* special_function */ 266 "r_imm16be", /* name */ 267 FALSE, /* partial_inplace */ 268 0x00000000, /* src_mask */ 269 0x0000ffff, /* dst_mask */ 270 FALSE), /* pcrel_offset */ 271 }; 272 273 static reloc_howto_type * 274 z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 275 bfd_reloc_code_real_type code) 276 { 277 enum 278 { 279 table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0]) 280 }; 281 unsigned int i; 282 283 for (i = 0; i < table_size; i++) 284 { 285 if (elf_z80_howto_table[i].r_type == code) 286 return &elf_z80_howto_table[i].howto; 287 } 288 289 printf ("%s:%d Not found BFD reloc type %d\n", __FILE__, __LINE__, code); 290 291 return NULL; 292 } 293 294 static reloc_howto_type * 295 z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) 296 { 297 enum 298 { 299 table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0]) 300 }; 301 unsigned int i; 302 303 for (i = 0; i < table_size; i++) 304 { 305 if (elf_z80_howto_table[i].howto.name != NULL 306 && strcasecmp (elf_z80_howto_table[i].howto.name, r_name) == 0) 307 return &elf_z80_howto_table[i].howto; 308 } 309 310 printf ("%s:%d Not found ELF reloc name `%s'\n", __FILE__, __LINE__, r_name); 311 312 return NULL; 313 } 314 315 static reloc_howto_type * 316 z80_rtype_to_howto (bfd *abfd, unsigned r_type) 317 { 318 enum 319 { 320 table_size = sizeof (elf_z80_howto_table) / sizeof (elf_z80_howto_table[0]) 321 }; 322 unsigned int i; 323 324 for (i = 0; i < table_size; i++) 325 { 326 if (elf_z80_howto_table[i].howto.type == r_type) 327 return &elf_z80_howto_table[i].howto; 328 } 329 330 /* xgettext:c-format */ 331 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 332 abfd, r_type); 333 return NULL; 334 } 335 336 /* Set the howto pointer for an z80 ELF reloc. */ 337 338 static bfd_boolean 339 z80_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) 340 { 341 unsigned int r_type = ELF32_R_TYPE (dst->r_info); 342 reloc_howto_type *howto = z80_rtype_to_howto (abfd, r_type); 343 if (howto != NULL) 344 { 345 cache_ptr->howto = howto; 346 return TRUE; 347 } 348 bfd_set_error (bfd_error_bad_value); 349 return FALSE; 350 } 351 352 static bfd_reloc_status_type 353 z80_elf_final_link_relocate (unsigned long r_type, 354 bfd *input_bfd, 355 bfd *output_bfd ATTRIBUTE_UNUSED, 356 asection *input_section ATTRIBUTE_UNUSED, 357 bfd_byte *contents, 358 bfd_vma offset, 359 bfd_vma value, 360 bfd_vma addend, 361 struct bfd_link_info *info ATTRIBUTE_UNUSED, 362 asection *sym_sec ATTRIBUTE_UNUSED, 363 int is_local ATTRIBUTE_UNUSED) 364 { 365 bfd_boolean r; 366 reloc_howto_type *howto; 367 368 switch (r_type) 369 { 370 case R_Z80_16_BE: 371 value += addend; 372 bfd_put_8 (input_bfd, value >> 8, contents + offset + 0); 373 bfd_put_8 (input_bfd, value >> 0, contents + offset + 1); 374 return bfd_reloc_ok; 375 } 376 377 howto = z80_rtype_to_howto (input_bfd, r_type); 378 if (howto == NULL) 379 return bfd_reloc_notsupported; 380 381 r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, 382 offset, value, addend); 383 return r ? bfd_reloc_ok : bfd_reloc_notsupported; 384 } 385 386 static bfd_boolean 387 z80_elf_relocate_section (bfd *output_bfd, 388 struct bfd_link_info *info, 389 bfd *input_bfd, 390 asection *input_section, 391 bfd_byte *contents, 392 Elf_Internal_Rela *relocs, 393 Elf_Internal_Sym *local_syms, 394 asection **local_sections) 395 { 396 Elf_Internal_Shdr *symtab_hdr; 397 struct elf_link_hash_entry **sym_hashes; 398 Elf_Internal_Rela *rel, *relend; 399 400 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 401 sym_hashes = elf_sym_hashes (input_bfd); 402 403 rel = relocs; 404 relend = relocs + input_section->reloc_count; 405 for (; rel < relend; rel++) 406 { 407 unsigned int r_type; 408 unsigned long r_symndx; 409 Elf_Internal_Sym *sym; 410 asection *sec; 411 struct elf_link_hash_entry *h; 412 bfd_vma relocation; 413 414 /* This is a final link. */ 415 r_symndx = ELF32_R_SYM (rel->r_info); 416 r_type = ELF32_R_TYPE (rel->r_info); 417 h = NULL; 418 sym = NULL; 419 sec = NULL; 420 if (r_symndx < symtab_hdr->sh_info) 421 { 422 sym = local_syms + r_symndx; 423 sec = local_sections[r_symndx]; 424 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 425 } 426 else 427 { 428 bfd_boolean unresolved_reloc, warned, ignored; 429 430 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 431 r_symndx, symtab_hdr, sym_hashes, 432 h, sec, relocation, 433 unresolved_reloc, warned, ignored); 434 } 435 436 if (sec != NULL && discarded_section (sec)) 437 { 438 /* For relocs against symbols from removed linkonce sections, 439 or sections discarded by a linker script, we just want the 440 section contents cleared. Avoid any special processing. */ 441 reloc_howto_type *howto; 442 howto = z80_rtype_to_howto (input_bfd, r_type); 443 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 444 rel, 1, relend, howto, 0, contents); 445 } 446 447 if (bfd_link_relocatable (info)) 448 continue; 449 450 451 z80_elf_final_link_relocate (r_type, input_bfd, output_bfd, 452 input_section, 453 contents, rel->r_offset, 454 relocation, rel->r_addend, 455 info, sec, h == NULL); 456 } 457 458 return TRUE; 459 } 460 461 /* The final processing done just before writing out a Z80 ELF object 462 file. This gets the Z80 architecture right based on the machine 463 number. */ 464 465 static bfd_boolean 466 z80_elf_final_write_processing (bfd *abfd) 467 { 468 unsigned long val = bfd_get_mach (abfd); 469 470 switch (val) 471 { 472 default: 473 _bfd_error_handler (_("%pB: unsupported bfd mach %#lx"), 474 abfd, val); 475 /* fall through */ 476 case bfd_mach_z80: 477 case bfd_mach_z80full: 478 case bfd_mach_z80strict: 479 val = EF_Z80_MACH_Z80; 480 break; 481 case bfd_mach_gbz80: 482 val = EF_Z80_MACH_GBZ80; 483 break; 484 case bfd_mach_z80n: 485 val = EF_Z80_MACH_Z80N; 486 break; 487 case bfd_mach_z180: 488 val = EF_Z80_MACH_Z180; 489 break; 490 case bfd_mach_ez80_z80: 491 val = EF_Z80_MACH_EZ80_Z80; 492 break; 493 case bfd_mach_ez80_adl: 494 val = EF_Z80_MACH_EZ80_ADL; 495 break; 496 case bfd_mach_r800: 497 val = EF_Z80_MACH_R800; 498 break; 499 } 500 elf_elfheader (abfd)->e_machine = EM_Z80; 501 elf_elfheader (abfd)->e_flags &= ~EF_Z80_MACH_MSK; 502 elf_elfheader (abfd)->e_flags |= val; 503 return _bfd_elf_final_write_processing (abfd); 504 } 505 506 /* Set the right machine number. */ 507 static bfd_boolean 508 z80_elf_object_p (bfd *abfd) 509 { 510 unsigned int mach; 511 512 if (elf_elfheader (abfd)->e_machine == EM_Z80) 513 { 514 int e_mach = elf_elfheader (abfd)->e_flags & EF_Z80_MACH_MSK; 515 switch (e_mach) 516 { 517 default: 518 _bfd_error_handler (_("%pB: unsupported mach %#x"), 519 abfd, e_mach); 520 /* fall through */ 521 case EF_Z80_MACH_Z80: 522 mach = bfd_mach_z80; 523 break; 524 case EF_Z80_MACH_GBZ80: 525 mach = bfd_mach_gbz80; 526 break; 527 case EF_Z80_MACH_Z180: 528 mach = bfd_mach_z180; 529 break; 530 case EF_Z80_MACH_EZ80_Z80: 531 mach = bfd_mach_ez80_z80; 532 break; 533 case EF_Z80_MACH_EZ80_ADL: 534 mach = bfd_mach_ez80_adl; 535 break; 536 case EF_Z80_MACH_R800: 537 mach = bfd_mach_r800; 538 break; 539 case EF_Z80_MACH_Z80N: 540 mach = bfd_mach_z80n; 541 break; 542 } 543 } 544 else 545 { 546 _bfd_error_handler (_("%pB: unsupported arch %#x"), 547 abfd, elf_elfheader (abfd)->e_machine); 548 mach = bfd_mach_z80; 549 } 550 return bfd_default_set_arch_mach (abfd, bfd_arch_z80, mach); 551 } 552 553 static int 554 z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, 555 const char * name) 556 { 557 return (name[0] == '.' && name[1] == 'L') || 558 _bfd_elf_is_local_label_name (abfd, name); 559 } 560 561 static bfd_reloc_status_type 562 z80_elf_16_be_reloc (bfd *abfd, 563 arelent *reloc_entry, 564 asymbol *symbol, 565 void *data, 566 asection *input_section, 567 bfd *output_bfd, 568 char **error_message) 569 { 570 bfd_vma val; 571 long x; 572 bfd_size_type octets = (reloc_entry->address 573 * OCTETS_PER_BYTE (abfd, input_section)); 574 575 /* If this is a relocatable link (output_bfd test tells us), just 576 call the generic function. Any adjustment will be done at final 577 link time. */ 578 if (output_bfd != NULL) 579 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, 580 input_section, output_bfd, error_message); 581 582 /* Get symbol value. */ 583 val = 0; 584 if (!bfd_is_com_section (symbol->section)) 585 val = symbol->value; 586 val += symbol->section->output_offset + input_section->output_offset; 587 if (symbol->section->output_section) 588 val += symbol->section->output_section->vma; 589 590 val += reloc_entry->addend; 591 if (reloc_entry->howto->partial_inplace) 592 { 593 x = bfd_get_8 (abfd, (bfd_byte *) data + octets + 0) * 0x100; 594 x += bfd_get_8 (abfd, (bfd_byte *) data + octets + 1); 595 x &= ~reloc_entry->howto->src_mask; 596 } 597 else 598 x = 0; 599 600 x |= val & reloc_entry->howto->dst_mask; 601 if (x < -0x8000 || x >= 0x10000) 602 return bfd_reloc_outofrange; 603 604 bfd_put_8 (abfd, x >> 8, (bfd_byte *) data + octets + 0); 605 bfd_put_8 (abfd, x >> 0, (bfd_byte *) data + octets + 1); 606 return bfd_reloc_ok; 607 } 608 609 #define ELF_ARCH bfd_arch_z80 610 #define ELF_MACHINE_CODE EM_Z80 611 #define ELF_MAXPAGESIZE 0x10000 612 613 #define TARGET_LITTLE_SYM z80_elf32_vec 614 #define TARGET_LITTLE_NAME "elf32-z80" 615 616 #define elf_backend_can_refcount 1 617 #define elf_backend_can_gc_sections 1 618 #define elf_backend_stack_align 1 619 #define elf_backend_rela_normal 1 620 621 #define elf_info_to_howto z80_info_to_howto_rela 622 #define elf_info_to_howto_rel z80_info_to_howto_rela 623 624 #define elf_backend_final_write_processing z80_elf_final_write_processing 625 #define elf_backend_object_p z80_elf_object_p 626 #define elf_backend_relocate_section z80_elf_relocate_section 627 628 #define bfd_elf32_bfd_reloc_type_lookup z80_reloc_type_lookup 629 #define bfd_elf32_bfd_reloc_name_lookup z80_reloc_name_lookup 630 #define bfd_elf32_bfd_is_local_label_name z80_is_local_label_name 631 632 #include "elf32-target.h" 633