1 1.1 skrll /* BFD back-end for Zilog Z80 COFF binaries. 2 1.1.1.10 christos Copyright (C) 2005-2026 Free Software Foundation, Inc. 3 1.1 skrll Contributed by Arnold Metselaar <arnold_m (at) operamail.com> 4 1.1 skrll 5 1.1 skrll This file is part of BFD, the Binary File Descriptor library. 6 1.1 skrll 7 1.1.1.3 christos This program is free software; you can redistribute it and/or modify 8 1.1 skrll it under the terms of the GNU General Public License as published by 9 1.1 skrll the Free Software Foundation; either version 3 of the License, or 10 1.1 skrll (at your option) any later version. 11 1.1 skrll 12 1.1 skrll This program is distributed in the hope that it will be useful, 13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 skrll GNU General Public License for more details. 16 1.1 skrll 17 1.1 skrll You should have received a copy of the GNU General Public License 18 1.1 skrll along with this program; if not, write to the Free Software 19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 skrll MA 02110-1301, USA. */ 21 1.1 skrll 22 1.1 skrll #include "sysdep.h" 23 1.1 skrll #include "bfd.h" 24 1.1 skrll #include "libbfd.h" 25 1.1 skrll #include "bfdlink.h" 26 1.1 skrll #include "coff/z80.h" 27 1.1 skrll #include "coff/internal.h" 28 1.1 skrll #include "libcoff.h" 29 1.1.1.6 christos #include "libiberty.h" 30 1.1 skrll 31 1.1 skrll #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0 32 1.1 skrll 33 1.1.1.7 christos typedef const struct { 34 1.1.1.6 christos bfd_reloc_code_real_type r_type; 35 1.1.1.6 christos reloc_howto_type howto; 36 1.1.1.6 christos } bfd_howto_type; 37 1.1 skrll 38 1.1.1.6 christos #define BFD_EMPTY_HOWTO(rt,x) {rt, EMPTY_HOWTO(x)} 39 1.1.1.6 christos #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 1.1.1.6 christos 41 1.1.1.6 christos static bfd_howto_type howto_table[] = 42 1.1.1.6 christos { 43 1.1.1.6 christos BFD_EMPTY_HOWTO (BFD_RELOC_NONE, 0), 44 1.1.1.6 christos 45 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_32, 46 1.1.1.6 christos R_IMM32, /* type */ 47 1.1.1.6 christos 0, /* rightshift */ 48 1.1.1.7 christos 4, /* size */ 49 1.1.1.6 christos 32, /* bitsize */ 50 1.1.1.7 christos false, /* pc_relative */ 51 1.1.1.6 christos 0, /* bitpos */ 52 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */ 53 1.1.1.6 christos 0, /* special_function */ 54 1.1.1.6 christos "r_imm32", /* name */ 55 1.1.1.7 christos false, /* partial_inplace */ 56 1.1.1.6 christos 0xffffffff, /* src_mask */ 57 1.1.1.6 christos 0xffffffff, /* dst_mask */ 58 1.1.1.7 christos false), /* pcrel_offset */ 59 1.1.1.6 christos 60 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_24, 61 1.1.1.6 christos R_IMM24, /* type */ 62 1.1.1.6 christos 0, /* rightshift */ 63 1.1.1.7 christos 3, /* size */ 64 1.1.1.6 christos 24, /* bitsize */ 65 1.1.1.7 christos false, /* pc_relative */ 66 1.1.1.6 christos 0, /* bitpos */ 67 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */ 68 1.1.1.6 christos 0, /* special_function */ 69 1.1.1.6 christos "r_imm24", /* name */ 70 1.1.1.7 christos false, /* partial_inplace */ 71 1.1.1.6 christos 0x00ffffff, /* src_mask */ 72 1.1.1.6 christos 0x00ffffff, /* dst_mask */ 73 1.1.1.7 christos false), /* pcrel_offset */ 74 1.1.1.6 christos 75 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_16, 76 1.1.1.6 christos R_IMM16, /* type */ 77 1.1.1.6 christos 0, /* rightshift */ 78 1.1.1.7 christos 2, /* size */ 79 1.1.1.6 christos 16, /* bitsize */ 80 1.1.1.7 christos false, /* pc_relative */ 81 1.1.1.6 christos 0, /* bitpos */ 82 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */ 83 1.1.1.6 christos 0, /* special_function */ 84 1.1.1.6 christos "r_imm16", /* name */ 85 1.1.1.7 christos false, /* partial_inplace */ 86 1.1.1.6 christos 0x0000ffff, /* src_mask */ 87 1.1.1.6 christos 0x0000ffff, /* dst_mask */ 88 1.1.1.7 christos false), /* pcrel_offset */ 89 1.1.1.6 christos 90 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_8, 91 1.1.1.6 christos R_IMM8, /* type */ 92 1.1.1.6 christos 0, /* rightshift */ 93 1.1.1.7 christos 1, /* size */ 94 1.1.1.6 christos 8, /* bitsize */ 95 1.1.1.7 christos false, /* pc_relative */ 96 1.1.1.6 christos 0, /* bitpos */ 97 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */ 98 1.1.1.6 christos 0, /* special_function */ 99 1.1.1.6 christos "r_imm8", /* name */ 100 1.1.1.7 christos false, /* partial_inplace */ 101 1.1.1.6 christos 0x000000ff, /* src_mask */ 102 1.1.1.6 christos 0x000000ff, /* dst_mask */ 103 1.1.1.7 christos false), /* pcrel_offset */ 104 1.1.1.6 christos 105 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_8_PCREL, 106 1.1.1.6 christos R_JR, /* type */ 107 1.1.1.6 christos 0, /* rightshift */ 108 1.1.1.7 christos 1, /* size */ 109 1.1.1.6 christos 8, /* bitsize */ 110 1.1.1.7 christos true, /* pc_relative */ 111 1.1.1.6 christos 0, /* bitpos */ 112 1.1.1.6 christos complain_overflow_signed, /* complain_on_overflow */ 113 1.1.1.6 christos 0, /* special_function */ 114 1.1.1.6 christos "r_jr", /* name */ 115 1.1.1.7 christos false, /* partial_inplace */ 116 1.1.1.6 christos 0, /* src_mask */ 117 1.1.1.6 christos 0xFF, /* dst_mask */ 118 1.1.1.7 christos true), /* pcrel_offset */ 119 1.1.1.6 christos 120 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_DISP8, 121 1.1.1.6 christos R_OFF8, /* type */ 122 1.1.1.6 christos 0, /* rightshift */ 123 1.1.1.7 christos 1, /* size */ 124 1.1.1.6 christos 8, /* bitsize */ 125 1.1.1.7 christos false, /* pc_relative */ 126 1.1.1.6 christos 0, /* bitpos */ 127 1.1.1.6 christos complain_overflow_signed, /* complain_on_overflow */ 128 1.1.1.6 christos 0, /* special_function */ 129 1.1.1.6 christos "r_off8", /* name */ 130 1.1.1.7 christos false, /* partial_inplace */ 131 1.1.1.6 christos 0, /* src_mask */ 132 1.1.1.6 christos 0xff, /* dst_mask */ 133 1.1.1.7 christos false), /* pcrel_offset */ 134 1.1.1.6 christos 135 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE0, 136 1.1.1.6 christos R_BYTE0, /* type */ 137 1.1.1.6 christos 0, /* rightshift */ 138 1.1.1.7 christos 1, /* size */ 139 1.1.1.6 christos 8, /* bitsize */ 140 1.1.1.7 christos false, /* pc_relative */ 141 1.1.1.6 christos 0, /* bitpos */ 142 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 143 1.1.1.6 christos 0, /* special_function */ 144 1.1.1.6 christos "r_byte0", /* name */ 145 1.1.1.7 christos false, /* partial_inplace */ 146 1.1.1.6 christos 0, /* src_mask */ 147 1.1.1.6 christos 0xff, /* dst_mask */ 148 1.1.1.7 christos false), /* pcrel_offset */ 149 1.1.1.6 christos 150 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE1, 151 1.1.1.6 christos R_BYTE1, /* type */ 152 1.1.1.6 christos 8, /* rightshift */ 153 1.1.1.7 christos 1, /* size */ 154 1.1.1.6 christos 8, /* bitsize */ 155 1.1.1.7 christos false, /* pc_relative */ 156 1.1.1.6 christos 0, /* bitpos */ 157 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 158 1.1.1.6 christos 0, /* special_function */ 159 1.1.1.6 christos "r_byte1", /* name */ 160 1.1.1.7 christos false, /* partial_inplace */ 161 1.1.1.6 christos 0, /* src_mask */ 162 1.1.1.6 christos 0xff, /* dst_mask */ 163 1.1.1.7 christos false), /* pcrel_offset */ 164 1.1.1.6 christos 165 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE2, 166 1.1.1.6 christos R_BYTE2, /* type */ 167 1.1.1.6 christos 16, /* rightshift */ 168 1.1.1.7 christos 1, /* size */ 169 1.1.1.6 christos 8, /* bitsize */ 170 1.1.1.7 christos false, /* pc_relative */ 171 1.1.1.6 christos 0, /* bitpos */ 172 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 173 1.1.1.6 christos 0, /* special_function */ 174 1.1.1.6 christos "r_byte2", /* name */ 175 1.1.1.7 christos false, /* partial_inplace */ 176 1.1.1.6 christos 0, /* src_mask */ 177 1.1.1.6 christos 0xff, /* dst_mask */ 178 1.1.1.7 christos false), /* pcrel_offset */ 179 1.1.1.6 christos 180 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_BYTE3, 181 1.1.1.6 christos R_BYTE3, /* type */ 182 1.1.1.6 christos 24, /* rightshift */ 183 1.1.1.7 christos 1, /* size */ 184 1.1.1.6 christos 8, /* bitsize */ 185 1.1.1.7 christos false, /* pc_relative */ 186 1.1.1.6 christos 0, /* bitpos */ 187 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 188 1.1.1.6 christos 0, /* special_function */ 189 1.1.1.6 christos "r_byte3", /* name */ 190 1.1.1.7 christos false, /* partial_inplace */ 191 1.1.1.6 christos 0, /* src_mask */ 192 1.1.1.6 christos 0xff, /* dst_mask */ 193 1.1.1.7 christos false), /* pcrel_offset */ 194 1.1.1.6 christos 195 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_WORD0, 196 1.1.1.6 christos R_WORD0, /* type */ 197 1.1.1.6 christos 0, /* rightshift */ 198 1.1.1.7 christos 2, /* size */ 199 1.1.1.6 christos 16, /* bitsize */ 200 1.1.1.7 christos false, /* pc_relative */ 201 1.1.1.6 christos 0, /* bitpos */ 202 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 203 1.1.1.6 christos 0, /* special_function */ 204 1.1.1.6 christos "r_word0", /* name */ 205 1.1.1.7 christos false, /* partial_inplace */ 206 1.1.1.6 christos 0, /* src_mask */ 207 1.1.1.6 christos 0xffff, /* dst_mask */ 208 1.1.1.7 christos false), /* pcrel_offset */ 209 1.1.1.6 christos 210 1.1.1.6 christos BFD_HOWTO (BFD_RELOC_Z80_WORD1, 211 1.1.1.6 christos R_WORD1, /* type */ 212 1.1.1.6 christos 16, /* rightshift */ 213 1.1.1.7 christos 2, /* size */ 214 1.1.1.6 christos 16, /* bitsize */ 215 1.1.1.7 christos false, /* pc_relative */ 216 1.1.1.6 christos 0, /* bitpos */ 217 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 218 1.1.1.6 christos 0, /* special_function */ 219 1.1.1.6 christos "r_word1", /* name */ 220 1.1.1.7 christos false, /* partial_inplace */ 221 1.1.1.6 christos 0, /* src_mask */ 222 1.1.1.6 christos 0xffff, /* dst_mask */ 223 1.1.1.7 christos false), /* pcrel_offset */ 224 1.1.1.7 christos 225 1.1.1.7 christos BFD_HOWTO (BFD_RELOC_Z80_16_BE, 226 1.1.1.7 christos R_IMM16BE, /* type */ 227 1.1.1.7 christos 0, /* rightshift */ 228 1.1.1.7 christos 2, /* size */ 229 1.1.1.7 christos 16, /* bitsize */ 230 1.1.1.7 christos false, /* pc_relative */ 231 1.1.1.7 christos 0, /* bitpos */ 232 1.1.1.7 christos complain_overflow_bitfield, /* complain_on_overflow */ 233 1.1.1.7 christos 0, /* special_function */ 234 1.1.1.7 christos "r_imm16be", /* name */ 235 1.1.1.7 christos false, /* partial_inplace */ 236 1.1.1.7 christos 0x0000ffff, /* src_mask */ 237 1.1.1.7 christos 0x0000ffff, /* dst_mask */ 238 1.1.1.7 christos false), /* pcrel_offset */ 239 1.1.1.6 christos }; 240 1.1.1.6 christos 241 1.1.1.6 christos #define NUM_HOWTOS ARRAY_SIZE (howto_table) 242 1.1 skrll 243 1.1 skrll #define BADMAG(x) Z80BADMAG(x) 244 1.1 skrll #define Z80 1 /* Customize coffcode.h. */ 245 1.1 skrll #define __A_MAGIC_SET__ 246 1.1 skrll 247 1.1 skrll /* Code to swap in the reloc. */ 248 1.1 skrll 249 1.1 skrll #define SWAP_IN_RELOC_OFFSET H_GET_32 250 1.1 skrll #define SWAP_OUT_RELOC_OFFSET H_PUT_32 251 1.1 skrll 252 1.1 skrll #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ 253 1.1 skrll dst->r_stuff[0] = 'S'; \ 254 1.1 skrll dst->r_stuff[1] = 'C'; 255 1.1 skrll 256 1.1 skrll /* Code to turn a r_type into a howto ptr, uses the above howto table. */ 257 1.1 skrll static void 258 1.1 skrll rtype2howto (arelent *internal, struct internal_reloc *dst) 259 1.1 skrll { 260 1.1.1.6 christos unsigned i; 261 1.1.1.6 christos for (i = 0; i < NUM_HOWTOS; i++) 262 1.1 skrll { 263 1.1.1.6 christos if (howto_table[i].howto.type == dst->r_type) 264 1.1.1.6 christos { 265 1.1.1.6 christos internal->howto = &howto_table[i].howto; 266 1.1.1.6 christos return; 267 1.1.1.6 christos } 268 1.1 skrll } 269 1.1.1.6 christos internal->howto = NULL; 270 1.1 skrll } 271 1.1 skrll 272 1.1 skrll #define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry) 273 1.1 skrll 274 1.1 skrll static reloc_howto_type * 275 1.1 skrll coff_z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 276 1.1 skrll bfd_reloc_code_real_type code) 277 1.1 skrll { 278 1.1.1.6 christos unsigned i; 279 1.1.1.6 christos for (i = 0; i < NUM_HOWTOS; i++) 280 1.1.1.6 christos if (howto_table[i].r_type == code) 281 1.1.1.6 christos return &howto_table[i].howto; 282 1.1.1.6 christos 283 1.1.1.6 christos BFD_FAIL (); 284 1.1.1.6 christos return NULL; 285 1.1 skrll } 286 1.1 skrll 287 1.1 skrll static reloc_howto_type * 288 1.1 skrll coff_z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 289 1.1 skrll const char *r_name) 290 1.1 skrll { 291 1.1.1.6 christos unsigned i; 292 1.1.1.6 christos for (i = 0; i < NUM_HOWTOS; i++) 293 1.1.1.6 christos if (strcasecmp(howto_table[i].howto.name, r_name) == 0) 294 1.1.1.6 christos return &howto_table[i].howto; 295 1.1 skrll 296 1.1 skrll return NULL; 297 1.1 skrll } 298 1.1 skrll 299 1.1 skrll /* Perform any necessary magic to the addend in a reloc entry. */ 300 1.1 skrll 301 1.1 skrll #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ 302 1.1 skrll cache_ptr->addend = ext_reloc.r_offset; 303 1.1 skrll 304 1.1 skrll #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ 305 1.1 skrll reloc_processing(relent, reloc, symbols, abfd, section) 306 1.1 skrll 307 1.1 skrll static void 308 1.1 skrll reloc_processing (arelent *relent, 309 1.1.1.5 christos struct internal_reloc *reloc, 310 1.1.1.5 christos asymbol **symbols, 311 1.1.1.5 christos bfd *abfd, 312 1.1.1.5 christos asection *section) 313 1.1 skrll { 314 1.1 skrll relent->address = reloc->r_vaddr; 315 1.1 skrll rtype2howto (relent, reloc); 316 1.1 skrll 317 1.1.1.8 christos if (reloc->r_symndx == -1 || symbols == NULL) 318 1.1.1.9 christos relent->sym_ptr_ptr = &bfd_abs_section_ptr->symbol; 319 1.1.1.7 christos else if (reloc->r_symndx >= 0 && reloc->r_symndx < obj_conv_table_size (abfd)) 320 1.1 skrll relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; 321 1.1 skrll else 322 1.1.1.7 christos { 323 1.1.1.7 christos _bfd_error_handler 324 1.1.1.7 christos /* xgettext:c-format */ 325 1.1.1.7 christos (_("%pB: warning: illegal symbol index %ld in relocs"), 326 1.1.1.7 christos abfd, reloc->r_symndx); 327 1.1.1.9 christos relent->sym_ptr_ptr = &bfd_abs_section_ptr->symbol; 328 1.1.1.7 christos } 329 1.1 skrll relent->addend = reloc->r_offset; 330 1.1 skrll relent->address -= section->vma; 331 1.1 skrll } 332 1.1 skrll 333 1.1.1.8 christos static bool 334 1.1 skrll extra_case (bfd *in_abfd, 335 1.1.1.5 christos struct bfd_link_info *link_info, 336 1.1.1.5 christos struct bfd_link_order *link_order, 337 1.1.1.5 christos arelent *reloc, 338 1.1.1.5 christos bfd_byte *data, 339 1.1.1.8 christos size_t *src_ptr, 340 1.1.1.8 christos size_t *dst_ptr) 341 1.1 skrll { 342 1.1 skrll asection * input_section = link_order->u.indirect.section; 343 1.1.1.8 christos bfd_size_type end = bfd_get_section_limit_octets (in_abfd, input_section); 344 1.1.1.8 christos bfd_size_type reloc_size = bfd_get_reloc_size (reloc->howto); 345 1.1.1.8 christos 346 1.1.1.8 christos if (*src_ptr > end 347 1.1.1.8 christos || reloc_size > end - *src_ptr) 348 1.1.1.8 christos { 349 1.1.1.8 christos link_info->callbacks->einfo 350 1.1.1.8 christos /* xgettext:c-format */ 351 1.1.1.8 christos (_("%X%P: %pB(%pA): relocation \"%pR\" goes out of range\n"), 352 1.1.1.8 christos in_abfd, input_section, reloc); 353 1.1.1.8 christos return false; 354 1.1.1.8 christos } 355 1.1 skrll 356 1.1.1.8 christos int val = bfd_coff_reloc16_get_value (reloc, link_info, input_section); 357 1.1 skrll switch (reloc->howto->type) 358 1.1 skrll { 359 1.1 skrll case R_OFF8: 360 1.1.1.6 christos if (reloc->howto->partial_inplace) 361 1.1.1.8 christos val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr) 362 1.1.1.8 christos & reloc->howto->src_mask); 363 1.1.1.8 christos if (val > 127 || val < -128) 364 1.1.1.8 christos { 365 1.1.1.8 christos link_info->callbacks->reloc_overflow 366 1.1.1.4 christos (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr), 367 1.1.1.4 christos reloc->howto->name, reloc->addend, input_section->owner, 368 1.1.1.4 christos input_section, reloc->address); 369 1.1.1.8 christos return false; 370 1.1.1.8 christos } 371 1.1.1.4 christos 372 1.1.1.8 christos bfd_put_8 (in_abfd, val, data + *dst_ptr); 373 1.1.1.8 christos *dst_ptr += 1; 374 1.1.1.8 christos *src_ptr += 1; 375 1.1 skrll break; 376 1.1 skrll 377 1.1.1.6 christos case R_BYTE3: 378 1.1.1.6 christos bfd_put_8 (in_abfd, val >> 24, data + *dst_ptr); 379 1.1.1.8 christos *dst_ptr += 1; 380 1.1.1.8 christos *src_ptr += 1; 381 1.1.1.6 christos break; 382 1.1.1.6 christos 383 1.1.1.6 christos case R_BYTE2: 384 1.1.1.6 christos bfd_put_8 (in_abfd, val >> 16, data + *dst_ptr); 385 1.1.1.8 christos *dst_ptr += 1; 386 1.1.1.8 christos *src_ptr += 1; 387 1.1.1.6 christos break; 388 1.1.1.6 christos 389 1.1.1.6 christos case R_BYTE1: 390 1.1.1.6 christos bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr); 391 1.1.1.8 christos *dst_ptr += 1; 392 1.1.1.8 christos *src_ptr += 1; 393 1.1.1.6 christos break; 394 1.1.1.6 christos 395 1.1 skrll case R_IMM8: 396 1.1.1.6 christos if (reloc->howto->partial_inplace) 397 1.1.1.8 christos val += bfd_get_8 (in_abfd, data + *src_ptr) & reloc->howto->src_mask; 398 1.1.1.7 christos /* Fall through. */ 399 1.1.1.6 christos case R_BYTE0: 400 1.1 skrll bfd_put_8 (in_abfd, val, data + *dst_ptr); 401 1.1.1.8 christos *dst_ptr += 1; 402 1.1.1.8 christos *src_ptr += 1; 403 1.1 skrll break; 404 1.1 skrll 405 1.1.1.6 christos case R_WORD1: 406 1.1.1.6 christos bfd_put_16 (in_abfd, val >> 16, data + *dst_ptr); 407 1.1.1.8 christos *dst_ptr += 2; 408 1.1.1.8 christos *src_ptr += 2; 409 1.1.1.6 christos break; 410 1.1.1.6 christos 411 1.1 skrll case R_IMM16: 412 1.1.1.6 christos if (reloc->howto->partial_inplace) 413 1.1.1.8 christos val += bfd_get_16 (in_abfd, data + *src_ptr) & reloc->howto->src_mask; 414 1.1.1.7 christos /* Fall through. */ 415 1.1.1.6 christos case R_WORD0: 416 1.1 skrll bfd_put_16 (in_abfd, val, data + *dst_ptr); 417 1.1.1.8 christos *dst_ptr += 2; 418 1.1.1.8 christos *src_ptr += 2; 419 1.1 skrll break; 420 1.1 skrll 421 1.1 skrll case R_IMM24: 422 1.1.1.6 christos if (reloc->howto->partial_inplace) 423 1.1.1.7 christos val += (bfd_get_24 (in_abfd, data + *src_ptr) 424 1.1.1.7 christos & reloc->howto->src_mask); 425 1.1.1.7 christos bfd_put_24 (in_abfd, val, data + *dst_ptr); 426 1.1.1.8 christos *dst_ptr += 3; 427 1.1.1.8 christos *src_ptr += 3; 428 1.1 skrll break; 429 1.1 skrll 430 1.1 skrll case R_IMM32: 431 1.1.1.6 christos if (reloc->howto->partial_inplace) 432 1.1.1.8 christos val += bfd_get_32 (in_abfd, data + *src_ptr) & reloc->howto->src_mask; 433 1.1 skrll bfd_put_32 (in_abfd, val, data + *dst_ptr); 434 1.1.1.8 christos *dst_ptr += 4; 435 1.1.1.8 christos *src_ptr += 4; 436 1.1 skrll break; 437 1.1 skrll 438 1.1 skrll case R_JR: 439 1.1 skrll { 440 1.1.1.8 christos if (reloc->howto->partial_inplace) 441 1.1.1.8 christos val += (signed char) (bfd_get_8 (in_abfd, data + *src_ptr) 442 1.1.1.8 christos & reloc->howto->src_mask); 443 1.1 skrll bfd_vma dot = (*dst_ptr 444 1.1 skrll + input_section->output_offset 445 1.1 skrll + input_section->output_section->vma); 446 1.1.1.8 christos bfd_signed_vma gap = val - dot; 447 1.1 skrll if (gap >= 128 || gap < -128) 448 1.1.1.8 christos { 449 1.1.1.8 christos link_info->callbacks->reloc_overflow 450 1.1.1.8 christos (link_info, NULL, bfd_asymbol_name (*reloc->sym_ptr_ptr), 451 1.1.1.8 christos reloc->howto->name, reloc->addend, input_section->owner, 452 1.1.1.8 christos input_section, reloc->address); 453 1.1.1.8 christos return false; 454 1.1.1.8 christos } 455 1.1.1.4 christos 456 1.1 skrll bfd_put_8 (in_abfd, gap, data + *dst_ptr); 457 1.1.1.8 christos *dst_ptr += 1; 458 1.1.1.8 christos *src_ptr += 1; 459 1.1 skrll break; 460 1.1 skrll } 461 1.1 skrll 462 1.1.1.7 christos case R_IMM16BE: 463 1.1.1.7 christos if (reloc->howto->partial_inplace) 464 1.1.1.8 christos val += ((bfd_get_8 (in_abfd, data + *src_ptr + 0) * 0x100 465 1.1.1.8 christos + bfd_get_8 (in_abfd, data + *src_ptr + 1)) 466 1.1.1.8 christos & reloc->howto->src_mask); 467 1.1.1.7 christos 468 1.1.1.8 christos bfd_put_8 (in_abfd, val >> 8, data + *dst_ptr + 0); 469 1.1.1.8 christos bfd_put_8 (in_abfd, val, data + *dst_ptr + 1); 470 1.1.1.8 christos *dst_ptr += 2; 471 1.1.1.8 christos *src_ptr += 2; 472 1.1.1.7 christos break; 473 1.1.1.7 christos 474 1.1 skrll default: 475 1.1.1.8 christos link_info->callbacks->einfo 476 1.1.1.8 christos /* xgettext:c-format */ 477 1.1.1.8 christos (_("%X%P: %pB(%pA): relocation \"%pR\" is not supported\n"), 478 1.1.1.8 christos in_abfd, input_section, reloc); 479 1.1.1.8 christos return false; 480 1.1 skrll } 481 1.1.1.8 christos return true; 482 1.1 skrll } 483 1.1 skrll 484 1.1.1.7 christos static bool 485 1.1.1.6 christos z80_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED, 486 1.1.1.6 christos const char * name) 487 1.1.1.6 christos { 488 1.1.1.6 christos return (name[0] == '.' && name[1] == 'L') || 489 1.1.1.6 christos _bfd_coff_is_local_label_name (abfd, name); 490 1.1.1.6 christos } 491 1.1.1.6 christos 492 1.1.1.6 christos #define coff_bfd_is_local_label_name z80_is_local_label_name 493 1.1.1.6 christos 494 1.1 skrll #define coff_reloc16_extra_cases extra_case 495 1.1 skrll #define coff_bfd_reloc_type_lookup coff_z80_reloc_type_lookup 496 1.1 skrll #define coff_bfd_reloc_name_lookup coff_z80_reloc_name_lookup 497 1.1 skrll 498 1.1 skrll #ifndef bfd_pe_print_pdata 499 1.1 skrll #define bfd_pe_print_pdata NULL 500 1.1 skrll #endif 501 1.1 skrll 502 1.1 skrll #include "coffcode.h" 503 1.1 skrll 504 1.1 skrll #undef coff_bfd_get_relocated_section_contents 505 1.1 skrll #define coff_bfd_get_relocated_section_contents \ 506 1.1 skrll bfd_coff_reloc16_get_relocated_section_contents 507 1.1 skrll 508 1.1 skrll #undef coff_bfd_relax_section 509 1.1 skrll #define coff_bfd_relax_section bfd_coff_reloc16_relax_section 510 1.1 skrll 511 1.1.1.3 christos CREATE_LITTLE_COFF_TARGET_VEC (z80_coff_vec, "coff-z80", 0, 512 1.1.1.3 christos SEC_CODE | SEC_DATA, '\0', NULL, 513 1.1 skrll COFF_SWAP_TABLE) 514 1.1 skrll 515