1 1.1 christos /* Matsushita 10200 specific support for 32-bit ELF 2 1.1.1.11 christos Copyright (C) 1996-2024 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of BFD, the Binary File Descriptor library. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program; if not, write to the Free Software 18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 1.1 christos MA 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #include "sysdep.h" 22 1.1 christos #include "bfd.h" 23 1.1 christos #include "libbfd.h" 24 1.1 christos #include "elf-bfd.h" 25 1.1 christos 26 1.1.1.10 christos static bool 27 1.1.1.2 christos mn10200_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int); 28 1.1.1.10 christos static bool 29 1.1.1.2 christos mn10200_elf_symbol_address_p (bfd *, asection *, Elf_Internal_Sym *, bfd_vma); 30 1.1 christos 31 1.1.1.2 christos enum reloc_type 32 1.1.1.2 christos { 33 1.1 christos R_MN10200_NONE = 0, 34 1.1 christos R_MN10200_32, 35 1.1 christos R_MN10200_16, 36 1.1 christos R_MN10200_8, 37 1.1 christos R_MN10200_24, 38 1.1 christos R_MN10200_PCREL8, 39 1.1 christos R_MN10200_PCREL16, 40 1.1 christos R_MN10200_PCREL24, 41 1.1 christos R_MN10200_MAX 42 1.1 christos }; 43 1.1 christos 44 1.1.1.2 christos static reloc_howto_type elf_mn10200_howto_table[] = 45 1.1.1.2 christos { 46 1.1 christos /* Dummy relocation. Does nothing. */ 47 1.1 christos HOWTO (R_MN10200_NONE, 48 1.1 christos 0, 49 1.1.1.5 christos 0, 50 1.1.1.10 christos 0, 51 1.1.1.10 christos false, 52 1.1 christos 0, 53 1.1.1.5 christos complain_overflow_dont, 54 1.1 christos bfd_elf_generic_reloc, 55 1.1 christos "R_MN10200_NONE", 56 1.1.1.10 christos false, 57 1.1 christos 0, 58 1.1 christos 0, 59 1.1.1.10 christos false), 60 1.1 christos /* Standard 32 bit reloc. */ 61 1.1 christos HOWTO (R_MN10200_32, 62 1.1 christos 0, 63 1.1.1.10 christos 4, 64 1.1 christos 32, 65 1.1.1.10 christos false, 66 1.1 christos 0, 67 1.1 christos complain_overflow_bitfield, 68 1.1 christos bfd_elf_generic_reloc, 69 1.1 christos "R_MN10200_32", 70 1.1.1.10 christos false, 71 1.1 christos 0xffffffff, 72 1.1 christos 0xffffffff, 73 1.1.1.10 christos false), 74 1.1 christos /* Standard 16 bit reloc. */ 75 1.1 christos HOWTO (R_MN10200_16, 76 1.1 christos 0, 77 1.1.1.10 christos 2, 78 1.1 christos 16, 79 1.1.1.10 christos false, 80 1.1 christos 0, 81 1.1 christos complain_overflow_bitfield, 82 1.1 christos bfd_elf_generic_reloc, 83 1.1 christos "R_MN10200_16", 84 1.1.1.10 christos false, 85 1.1 christos 0xffff, 86 1.1 christos 0xffff, 87 1.1.1.10 christos false), 88 1.1 christos /* Standard 8 bit reloc. */ 89 1.1 christos HOWTO (R_MN10200_8, 90 1.1 christos 0, 91 1.1.1.10 christos 1, 92 1.1 christos 8, 93 1.1.1.10 christos false, 94 1.1 christos 0, 95 1.1 christos complain_overflow_bitfield, 96 1.1 christos bfd_elf_generic_reloc, 97 1.1 christos "R_MN10200_8", 98 1.1.1.10 christos false, 99 1.1 christos 0xff, 100 1.1 christos 0xff, 101 1.1.1.10 christos false), 102 1.1 christos /* Standard 24 bit reloc. */ 103 1.1 christos HOWTO (R_MN10200_24, 104 1.1 christos 0, 105 1.1.1.10 christos 4, 106 1.1 christos 24, 107 1.1.1.10 christos false, 108 1.1 christos 0, 109 1.1 christos complain_overflow_bitfield, 110 1.1 christos bfd_elf_generic_reloc, 111 1.1 christos "R_MN10200_24", 112 1.1.1.10 christos false, 113 1.1 christos 0xffffff, 114 1.1 christos 0xffffff, 115 1.1.1.10 christos false), 116 1.1 christos /* Simple 8 pc-relative reloc. */ 117 1.1 christos HOWTO (R_MN10200_PCREL8, 118 1.1 christos 0, 119 1.1.1.10 christos 1, 120 1.1 christos 8, 121 1.1.1.10 christos true, 122 1.1 christos 0, 123 1.1 christos complain_overflow_bitfield, 124 1.1 christos bfd_elf_generic_reloc, 125 1.1 christos "R_MN10200_PCREL8", 126 1.1.1.10 christos false, 127 1.1 christos 0xff, 128 1.1 christos 0xff, 129 1.1.1.10 christos true), 130 1.1 christos /* Simple 16 pc-relative reloc. */ 131 1.1 christos HOWTO (R_MN10200_PCREL16, 132 1.1 christos 0, 133 1.1.1.10 christos 2, 134 1.1 christos 16, 135 1.1.1.10 christos true, 136 1.1 christos 0, 137 1.1 christos complain_overflow_bitfield, 138 1.1 christos bfd_elf_generic_reloc, 139 1.1 christos "R_MN10200_PCREL16", 140 1.1.1.10 christos false, 141 1.1 christos 0xffff, 142 1.1 christos 0xffff, 143 1.1.1.10 christos true), 144 1.1 christos /* Simple 32bit pc-relative reloc with a 1 byte adjustment 145 1.1 christos to get the pc-relative offset correct. */ 146 1.1 christos HOWTO (R_MN10200_PCREL24, 147 1.1 christos 0, 148 1.1.1.10 christos 4, 149 1.1 christos 24, 150 1.1.1.10 christos true, 151 1.1 christos 0, 152 1.1 christos complain_overflow_bitfield, 153 1.1 christos bfd_elf_generic_reloc, 154 1.1 christos "R_MN10200_PCREL24", 155 1.1.1.10 christos false, 156 1.1 christos 0xffffff, 157 1.1 christos 0xffffff, 158 1.1.1.10 christos true), 159 1.1 christos }; 160 1.1 christos 161 1.1.1.2 christos struct mn10200_reloc_map 162 1.1.1.2 christos { 163 1.1 christos bfd_reloc_code_real_type bfd_reloc_val; 164 1.1 christos unsigned char elf_reloc_val; 165 1.1 christos }; 166 1.1 christos 167 1.1.1.2 christos static const struct mn10200_reloc_map mn10200_reloc_map[] = 168 1.1.1.2 christos { 169 1.1 christos { BFD_RELOC_NONE , R_MN10200_NONE , }, 170 1.1 christos { BFD_RELOC_32 , R_MN10200_32 , }, 171 1.1 christos { BFD_RELOC_16 , R_MN10200_16 , }, 172 1.1 christos { BFD_RELOC_8 , R_MN10200_8 , }, 173 1.1 christos { BFD_RELOC_24 , R_MN10200_24 , }, 174 1.1 christos { BFD_RELOC_8_PCREL , R_MN10200_PCREL8 , }, 175 1.1 christos { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, }, 176 1.1 christos { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, }, 177 1.1 christos }; 178 1.1 christos 179 1.1 christos static reloc_howto_type * 180 1.1.1.2 christos bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 181 1.1.1.2 christos bfd_reloc_code_real_type code) 182 1.1 christos { 183 1.1 christos unsigned int i; 184 1.1 christos 185 1.1 christos for (i = 0; 186 1.1 christos i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map); 187 1.1 christos i++) 188 1.1 christos { 189 1.1 christos if (mn10200_reloc_map[i].bfd_reloc_val == code) 190 1.1 christos return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val]; 191 1.1 christos } 192 1.1 christos 193 1.1 christos return NULL; 194 1.1 christos } 195 1.1 christos 196 1.1 christos static reloc_howto_type * 197 1.1 christos bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 198 1.1 christos const char *r_name) 199 1.1 christos { 200 1.1 christos unsigned int i; 201 1.1 christos 202 1.1 christos for (i = 0; 203 1.1 christos i < (sizeof (elf_mn10200_howto_table) 204 1.1 christos / sizeof (elf_mn10200_howto_table[0])); 205 1.1 christos i++) 206 1.1 christos if (elf_mn10200_howto_table[i].name != NULL 207 1.1 christos && strcasecmp (elf_mn10200_howto_table[i].name, r_name) == 0) 208 1.1 christos return &elf_mn10200_howto_table[i]; 209 1.1 christos 210 1.1 christos return NULL; 211 1.1 christos } 212 1.1 christos 213 1.1 christos /* Set the howto pointer for an MN10200 ELF reloc. */ 214 1.1 christos 215 1.1.1.10 christos static bool 216 1.1.1.8 christos mn10200_info_to_howto (bfd *abfd, 217 1.1.1.2 christos arelent *cache_ptr, 218 1.1.1.2 christos Elf_Internal_Rela *dst) 219 1.1 christos { 220 1.1 christos unsigned int r_type; 221 1.1 christos 222 1.1 christos r_type = ELF32_R_TYPE (dst->r_info); 223 1.1.1.8 christos if (r_type >= (unsigned int) R_MN10200_MAX) 224 1.1.1.8 christos { 225 1.1.1.8 christos /* xgettext:c-format */ 226 1.1.1.8 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 227 1.1.1.8 christos abfd, r_type); 228 1.1.1.8 christos bfd_set_error (bfd_error_bad_value); 229 1.1.1.10 christos return false; 230 1.1.1.8 christos } 231 1.1.1.9 christos 232 1.1 christos cache_ptr->howto = &elf_mn10200_howto_table[r_type]; 233 1.1.1.8 christos return cache_ptr->howto != NULL; 234 1.1 christos } 235 1.1 christos 236 1.1 christos /* Perform a relocation as part of a final link. */ 237 1.1 christos 238 1.1 christos static bfd_reloc_status_type 239 1.1.1.2 christos mn10200_elf_final_link_relocate (reloc_howto_type *howto, 240 1.1.1.2 christos bfd *input_bfd, 241 1.1.1.2 christos bfd *output_bfd ATTRIBUTE_UNUSED, 242 1.1.1.2 christos asection *input_section, 243 1.1.1.2 christos bfd_byte *contents, 244 1.1.1.2 christos bfd_vma offset, 245 1.1.1.2 christos bfd_vma value, 246 1.1.1.2 christos bfd_vma addend, 247 1.1.1.2 christos struct bfd_link_info *info ATTRIBUTE_UNUSED, 248 1.1.1.2 christos asection *sym_sec ATTRIBUTE_UNUSED, 249 1.1.1.2 christos int is_local ATTRIBUTE_UNUSED) 250 1.1 christos { 251 1.1 christos unsigned long r_type = howto->type; 252 1.1 christos bfd_byte *hit_data = contents + offset; 253 1.1 christos 254 1.1 christos switch (r_type) 255 1.1 christos { 256 1.1 christos 257 1.1 christos case R_MN10200_NONE: 258 1.1 christos return bfd_reloc_ok; 259 1.1 christos 260 1.1 christos case R_MN10200_32: 261 1.1 christos value += addend; 262 1.1 christos bfd_put_32 (input_bfd, value, hit_data); 263 1.1 christos return bfd_reloc_ok; 264 1.1 christos 265 1.1 christos case R_MN10200_16: 266 1.1 christos value += addend; 267 1.1 christos 268 1.1 christos if ((long) value > 0x7fff || (long) value < -0x8000) 269 1.1 christos return bfd_reloc_overflow; 270 1.1 christos 271 1.1 christos bfd_put_16 (input_bfd, value, hit_data); 272 1.1 christos return bfd_reloc_ok; 273 1.1 christos 274 1.1 christos case R_MN10200_8: 275 1.1 christos value += addend; 276 1.1 christos 277 1.1 christos if ((long) value > 0x7f || (long) value < -0x80) 278 1.1 christos return bfd_reloc_overflow; 279 1.1 christos 280 1.1 christos bfd_put_8 (input_bfd, value, hit_data); 281 1.1 christos return bfd_reloc_ok; 282 1.1 christos 283 1.1 christos case R_MN10200_24: 284 1.1 christos value += addend; 285 1.1 christos 286 1.1 christos if ((long) value > 0x7fffff || (long) value < -0x800000) 287 1.1 christos return bfd_reloc_overflow; 288 1.1 christos 289 1.1 christos value &= 0xffffff; 290 1.1 christos value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000); 291 1.1 christos bfd_put_32 (input_bfd, value, hit_data); 292 1.1 christos return bfd_reloc_ok; 293 1.1 christos 294 1.1 christos case R_MN10200_PCREL8: 295 1.1 christos value -= (input_section->output_section->vma 296 1.1 christos + input_section->output_offset); 297 1.1 christos value -= (offset + 1); 298 1.1 christos value += addend; 299 1.1 christos 300 1.1 christos if ((long) value > 0xff || (long) value < -0x100) 301 1.1 christos return bfd_reloc_overflow; 302 1.1 christos 303 1.1 christos bfd_put_8 (input_bfd, value, hit_data); 304 1.1 christos return bfd_reloc_ok; 305 1.1 christos 306 1.1 christos case R_MN10200_PCREL16: 307 1.1 christos value -= (input_section->output_section->vma 308 1.1 christos + input_section->output_offset); 309 1.1 christos value -= (offset + 2); 310 1.1 christos value += addend; 311 1.1 christos 312 1.1 christos if ((long) value > 0xffff || (long) value < -0x10000) 313 1.1 christos return bfd_reloc_overflow; 314 1.1 christos 315 1.1 christos bfd_put_16 (input_bfd, value, hit_data); 316 1.1 christos return bfd_reloc_ok; 317 1.1 christos 318 1.1 christos case R_MN10200_PCREL24: 319 1.1 christos value -= (input_section->output_section->vma 320 1.1 christos + input_section->output_offset); 321 1.1 christos value -= (offset + 3); 322 1.1 christos value += addend; 323 1.1 christos 324 1.1 christos if ((long) value > 0xffffff || (long) value < -0x1000000) 325 1.1 christos return bfd_reloc_overflow; 326 1.1 christos 327 1.1 christos value &= 0xffffff; 328 1.1 christos value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000); 329 1.1 christos bfd_put_32 (input_bfd, value, hit_data); 330 1.1 christos return bfd_reloc_ok; 331 1.1 christos 332 1.1 christos default: 333 1.1 christos return bfd_reloc_notsupported; 334 1.1 christos } 335 1.1 christos } 336 1.1 christos 337 1.1 christos /* Relocate an MN10200 ELF section. */ 339 1.1.1.2 christos static int 340 1.1.1.2 christos mn10200_elf_relocate_section (bfd *output_bfd, 341 1.1.1.2 christos struct bfd_link_info *info, 342 1.1.1.2 christos bfd *input_bfd, 343 1.1.1.2 christos asection *input_section, 344 1.1.1.2 christos bfd_byte *contents, 345 1.1.1.2 christos Elf_Internal_Rela *relocs, 346 1.1.1.2 christos Elf_Internal_Sym *local_syms, 347 1.1 christos asection **local_sections) 348 1.1 christos { 349 1.1 christos Elf_Internal_Shdr *symtab_hdr; 350 1.1 christos struct elf_link_hash_entry **sym_hashes; 351 1.1 christos Elf_Internal_Rela *rel, *relend; 352 1.1 christos 353 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 354 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 355 1.1 christos 356 1.1 christos rel = relocs; 357 1.1 christos relend = relocs + input_section->reloc_count; 358 1.1 christos for (; rel < relend; rel++) 359 1.1 christos { 360 1.1 christos int r_type; 361 1.1 christos reloc_howto_type *howto; 362 1.1 christos unsigned long r_symndx; 363 1.1 christos Elf_Internal_Sym *sym; 364 1.1 christos asection *sec; 365 1.1 christos struct elf_link_hash_entry *h; 366 1.1 christos bfd_vma relocation; 367 1.1 christos bfd_reloc_status_type r; 368 1.1 christos 369 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 370 1.1 christos r_type = ELF32_R_TYPE (rel->r_info); 371 1.1 christos howto = elf_mn10200_howto_table + r_type; 372 1.1 christos 373 1.1 christos h = NULL; 374 1.1 christos sym = NULL; 375 1.1 christos sec = NULL; 376 1.1 christos if (r_symndx < symtab_hdr->sh_info) 377 1.1 christos { 378 1.1 christos sym = local_syms + r_symndx; 379 1.1 christos sec = local_sections[r_symndx]; 380 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 381 1.1 christos } 382 1.1 christos else 383 1.1.1.10 christos { 384 1.1 christos bool unresolved_reloc, warned, ignored; 385 1.1 christos 386 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 387 1.1 christos r_symndx, symtab_hdr, sym_hashes, 388 1.1.1.3 christos h, sec, relocation, 389 1.1 christos unresolved_reloc, warned, ignored); 390 1.1 christos } 391 1.1.1.2 christos 392 1.1 christos if (sec != NULL && discarded_section (sec)) 393 1.1.1.2 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 394 1.1 christos rel, 1, relend, howto, 0, contents); 395 1.1.1.6 christos 396 1.1 christos if (bfd_link_relocatable (info)) 397 1.1 christos continue; 398 1.1 christos 399 1.1 christos r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd, 400 1.1 christos input_section, 401 1.1 christos contents, rel->r_offset, 402 1.1 christos relocation, rel->r_addend, 403 1.1 christos info, sec, h == NULL); 404 1.1 christos 405 1.1 christos if (r != bfd_reloc_ok) 406 1.1 christos { 407 1.1 christos const char *name; 408 1.1 christos const char *msg = (const char *) 0; 409 1.1 christos 410 1.1 christos if (h != NULL) 411 1.1 christos name = h->root.root.string; 412 1.1 christos else 413 1.1 christos { 414 1.1 christos name = (bfd_elf_string_from_elf_section 415 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name)); 416 1.1.1.9 christos if (name == NULL || *name == '\0') 417 1.1 christos name = bfd_section_name (sec); 418 1.1 christos } 419 1.1 christos 420 1.1 christos switch (r) 421 1.1 christos { 422 1.1.1.6 christos case bfd_reloc_overflow: 423 1.1.1.6 christos (*info->callbacks->reloc_overflow) 424 1.1.1.6 christos (info, (h ? &h->root : NULL), name, howto->name, 425 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 426 1.1 christos break; 427 1.1 christos 428 1.1.1.6 christos case bfd_reloc_undefined: 429 1.1.1.6 christos (*info->callbacks->undefined_symbol) (info, name, input_bfd, 430 1.1.1.10 christos input_section, 431 1.1 christos rel->r_offset, true); 432 1.1 christos break; 433 1.1 christos 434 1.1 christos case bfd_reloc_outofrange: 435 1.1 christos msg = _("internal error: out of range error"); 436 1.1 christos goto common_error; 437 1.1 christos 438 1.1 christos case bfd_reloc_notsupported: 439 1.1 christos msg = _("internal error: unsupported relocation error"); 440 1.1 christos goto common_error; 441 1.1 christos 442 1.1 christos case bfd_reloc_dangerous: 443 1.1 christos msg = _("internal error: dangerous error"); 444 1.1 christos goto common_error; 445 1.1 christos 446 1.1 christos default: 447 1.1 christos msg = _("internal error: unknown error"); 448 1.1 christos /* fall through */ 449 1.1 christos 450 1.1.1.6 christos common_error: 451 1.1.1.6 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 452 1.1 christos input_section, rel->r_offset); 453 1.1 christos break; 454 1.1 christos } 455 1.1 christos } 456 1.1 christos } 457 1.1.1.10 christos 458 1.1 christos return true; 459 1.1 christos } 460 1.1.1.2 christos 461 1.1.1.2 christos /* Delete some bytes from a section while relaxing. */ 462 1.1.1.10 christos 463 1.1.1.2 christos static bool 464 1.1.1.2 christos mn10200_elf_relax_delete_bytes (bfd *abfd, asection *sec, 465 1.1.1.2 christos bfd_vma addr, int count) 466 1.1.1.2 christos { 467 1.1.1.2 christos Elf_Internal_Shdr *symtab_hdr; 468 1.1.1.2 christos unsigned int sec_shndx; 469 1.1.1.2 christos bfd_byte *contents; 470 1.1.1.2 christos Elf_Internal_Rela *irel, *irelend; 471 1.1.1.2 christos bfd_vma toaddr; 472 1.1.1.2 christos Elf_Internal_Sym *isym; 473 1.1.1.2 christos Elf_Internal_Sym *isymend; 474 1.1.1.2 christos struct elf_link_hash_entry **sym_hashes; 475 1.1.1.2 christos struct elf_link_hash_entry **end_hashes; 476 1.1.1.2 christos unsigned int symcount; 477 1.1.1.2 christos 478 1.1.1.2 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 479 1.1.1.2 christos 480 1.1.1.2 christos contents = elf_section_data (sec)->this_hdr.contents; 481 1.1.1.2 christos 482 1.1.1.2 christos toaddr = sec->size; 483 1.1.1.2 christos 484 1.1.1.2 christos irel = elf_section_data (sec)->relocs; 485 1.1.1.2 christos irelend = irel + sec->reloc_count; 486 1.1.1.2 christos 487 1.1.1.2 christos /* Actually delete the bytes. */ 488 1.1.1.2 christos memmove (contents + addr, contents + addr + count, 489 1.1.1.2 christos (size_t) (toaddr - addr - count)); 490 1.1.1.2 christos sec->size -= count; 491 1.1.1.2 christos 492 1.1.1.2 christos /* Adjust all the relocs. */ 493 1.1.1.2 christos for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 494 1.1.1.2 christos { 495 1.1.1.2 christos /* Get the new reloc address. */ 496 1.1.1.2 christos if ((irel->r_offset > addr 497 1.1.1.2 christos && irel->r_offset < toaddr)) 498 1.1.1.2 christos irel->r_offset -= count; 499 1.1.1.2 christos } 500 1.1.1.2 christos 501 1.1.1.2 christos /* Adjust the local symbols defined in this section. */ 502 1.1.1.2 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 503 1.1.1.2 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents; 504 1.1.1.2 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 505 1.1.1.2 christos { 506 1.1.1.2 christos if (isym->st_shndx == sec_shndx 507 1.1.1.2 christos && isym->st_value > addr 508 1.1.1.2 christos && isym->st_value < toaddr) 509 1.1.1.2 christos isym->st_value -= count; 510 1.1.1.2 christos } 511 1.1.1.2 christos 512 1.1.1.2 christos /* Now adjust the global symbols defined in this section. */ 513 1.1.1.2 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 514 1.1.1.2 christos - symtab_hdr->sh_info); 515 1.1.1.2 christos sym_hashes = elf_sym_hashes (abfd); 516 1.1.1.2 christos end_hashes = sym_hashes + symcount; 517 1.1.1.2 christos for (; sym_hashes < end_hashes; sym_hashes++) 518 1.1.1.2 christos { 519 1.1.1.2 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 520 1.1.1.2 christos if ((sym_hash->root.type == bfd_link_hash_defined 521 1.1.1.2 christos || sym_hash->root.type == bfd_link_hash_defweak) 522 1.1.1.2 christos && sym_hash->root.u.def.section == sec 523 1.1.1.2 christos && sym_hash->root.u.def.value > addr 524 1.1.1.2 christos && sym_hash->root.u.def.value < toaddr) 525 1.1.1.2 christos { 526 1.1.1.2 christos sym_hash->root.u.def.value -= count; 527 1.1.1.2 christos } 528 1.1.1.2 christos } 529 1.1.1.10 christos 530 1.1.1.2 christos return true; 531 1.1.1.2 christos } 532 1.1 christos 533 1.1 christos /* This function handles relaxing for the mn10200. 534 1.1 christos 535 1.1 christos There are quite a few relaxing opportunities available on the mn10200: 536 1.1.1.8 christos 537 1.1 christos * jsr:24 -> jsr:16 2 bytes 538 1.1 christos 539 1.1 christos * jmp:24 -> jmp:16 2 bytes 540 1.1 christos * jmp:16 -> bra:8 1 byte 541 1.1 christos 542 1.1 christos * If the previous instruction is a conditional branch 543 1.1 christos around the jump/bra, we may be able to reverse its condition 544 1.1 christos and change its target to the jump's target. The jump/bra 545 1.1 christos can then be deleted. 2 bytes 546 1.1 christos 547 1.1 christos * mov abs24 -> mov abs16 2 byte savings 548 1.1 christos 549 1.1 christos * Most instructions which accept imm24 can relax to imm16 2 bytes 550 1.1 christos - Most instructions which accept imm16 can relax to imm8 1 byte 551 1.1 christos 552 1.1 christos * Most instructions which accept d24 can relax to d16 2 bytes 553 1.1 christos - Most instructions which accept d16 can relax to d8 1 byte 554 1.1 christos 555 1.1 christos abs24, imm24, d24 all look the same at the reloc level. It 556 1.1 christos might make the code simpler if we had different relocs for 557 1.1 christos the various relaxable operand types. 558 1.1 christos 559 1.1 christos We don't handle imm16->imm8 or d16->d8 as they're very rare 560 1.1 christos and somewhat more difficult to support. */ 561 1.1.1.10 christos 562 1.1.1.2 christos static bool 563 1.1.1.2 christos mn10200_elf_relax_section (bfd *abfd, 564 1.1.1.2 christos asection *sec, 565 1.1.1.10 christos struct bfd_link_info *link_info, 566 1.1 christos bool *again) 567 1.1 christos { 568 1.1 christos Elf_Internal_Shdr *symtab_hdr; 569 1.1 christos Elf_Internal_Rela *internal_relocs; 570 1.1 christos Elf_Internal_Rela *irel, *irelend; 571 1.1 christos bfd_byte *contents = NULL; 572 1.1 christos Elf_Internal_Sym *isymbuf = NULL; 573 1.1 christos 574 1.1.1.10 christos /* Assume nothing changes. */ 575 1.1 christos *again = false; 576 1.1 christos 577 1.1 christos /* We don't have to do anything for a relocatable link, if 578 1.1 christos this section does not have relocs, or if this is not a 579 1.1.1.6 christos code section. */ 580 1.1 christos if (bfd_link_relocatable (link_info) 581 1.1.1.11 christos || sec->reloc_count == 0 582 1.1.1.11 christos || (sec->flags & SEC_RELOC) == 0 583 1.1 christos || (sec->flags & SEC_HAS_CONTENTS) == 0 584 1.1.1.10 christos || (sec->flags & SEC_CODE) == 0) 585 1.1 christos return true; 586 1.1 christos 587 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 588 1.1 christos 589 1.1 christos /* Get a copy of the native relocations. */ 590 1.1.1.2 christos internal_relocs = (_bfd_elf_link_read_relocs 591 1.1 christos (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, 592 1.1 christos link_info->keep_memory)); 593 1.1 christos if (internal_relocs == NULL) 594 1.1 christos goto error_return; 595 1.1 christos 596 1.1 christos /* Walk through them looking for relaxing opportunities. */ 597 1.1 christos irelend = internal_relocs + sec->reloc_count; 598 1.1 christos for (irel = internal_relocs; irel < irelend; irel++) 599 1.1 christos { 600 1.1 christos bfd_vma symval; 601 1.1 christos 602 1.1 christos /* If this isn't something that can be relaxed, then ignore 603 1.1 christos this reloc. */ 604 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE 605 1.1 christos || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8 606 1.1 christos || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX) 607 1.1 christos continue; 608 1.1 christos 609 1.1 christos /* Get the section contents if we haven't done so already. */ 610 1.1 christos if (contents == NULL) 611 1.1 christos { 612 1.1 christos /* Get cached copy if it exists. */ 613 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL) 614 1.1 christos contents = elf_section_data (sec)->this_hdr.contents; 615 1.1 christos else 616 1.1 christos { 617 1.1 christos /* Go get them off disk. */ 618 1.1 christos if (!bfd_malloc_and_get_section (abfd, sec, &contents)) 619 1.1 christos goto error_return; 620 1.1 christos } 621 1.1 christos } 622 1.1 christos 623 1.1 christos /* Read this BFD's local symbols if we haven't done so already. */ 624 1.1 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0) 625 1.1 christos { 626 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 627 1.1 christos if (isymbuf == NULL) 628 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 629 1.1 christos symtab_hdr->sh_info, 0, 630 1.1 christos NULL, NULL, NULL); 631 1.1 christos if (isymbuf == NULL) 632 1.1 christos goto error_return; 633 1.1 christos } 634 1.1 christos 635 1.1 christos /* Get the value of the symbol referred to by the reloc. */ 636 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 637 1.1 christos { 638 1.1 christos /* A local symbol. */ 639 1.1 christos Elf_Internal_Sym *isym; 640 1.1 christos asection *sym_sec; 641 1.1 christos 642 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 643 1.1 christos if (isym->st_shndx == SHN_UNDEF) 644 1.1 christos sym_sec = bfd_und_section_ptr; 645 1.1 christos else if (isym->st_shndx == SHN_ABS) 646 1.1 christos sym_sec = bfd_abs_section_ptr; 647 1.1 christos else if (isym->st_shndx == SHN_COMMON) 648 1.1 christos sym_sec = bfd_com_section_ptr; 649 1.1 christos else 650 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 651 1.1 christos symval = (isym->st_value 652 1.1 christos + sym_sec->output_section->vma 653 1.1 christos + sym_sec->output_offset); 654 1.1 christos } 655 1.1 christos else 656 1.1 christos { 657 1.1 christos unsigned long indx; 658 1.1 christos struct elf_link_hash_entry *h; 659 1.1 christos 660 1.1 christos /* An external symbol. */ 661 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 662 1.1 christos h = elf_sym_hashes (abfd)[indx]; 663 1.1 christos BFD_ASSERT (h != NULL); 664 1.1 christos if (h->root.type != bfd_link_hash_defined 665 1.1 christos && h->root.type != bfd_link_hash_defweak) 666 1.1 christos { 667 1.1.1.8 christos /* This appears to be a reference to an undefined 668 1.1.1.8 christos symbol. Just ignore it--it will be caught by the 669 1.1 christos regular reloc processing. */ 670 1.1 christos continue; 671 1.1 christos } 672 1.1 christos 673 1.1 christos symval = (h->root.u.def.value 674 1.1 christos + h->root.u.def.section->output_section->vma 675 1.1 christos + h->root.u.def.section->output_offset); 676 1.1 christos } 677 1.1 christos 678 1.1 christos /* For simplicity of coding, we are going to modify the section 679 1.1 christos contents, the section relocs, and the BFD symbol table. We 680 1.1 christos must tell the rest of the code not to free up this 681 1.1 christos information. It would be possible to instead create a table 682 1.1 christos of changes which have to be made, as is done in coff-mips.c; 683 1.1 christos that would be more work, but would require less memory when 684 1.1 christos the linker is run. */ 685 1.1 christos 686 1.1 christos /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative 687 1.1 christos branch/call. */ 688 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24) 689 1.1 christos { 690 1.1 christos bfd_vma value = symval; 691 1.1 christos 692 1.1 christos /* Deal with pc-relative gunk. */ 693 1.1 christos value -= (sec->output_section->vma + sec->output_offset); 694 1.1 christos value -= (irel->r_offset + 3); 695 1.1 christos value += irel->r_addend; 696 1.1 christos 697 1.1 christos /* See if the value will fit in 16 bits, note the high value is 698 1.1 christos 0x7fff + 2 as the target will be two bytes closer if we are 699 1.1 christos able to relax. */ 700 1.1 christos if ((long) value < 0x8001 && (long) value > -0x8000) 701 1.1 christos { 702 1.1 christos unsigned char code; 703 1.1 christos 704 1.1 christos /* Get the opcode. */ 705 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1); 706 1.1 christos 707 1.1 christos if (code != 0xe0 && code != 0xe1) 708 1.1 christos continue; 709 1.1 christos 710 1.1 christos /* Note that we've changed the relocs, section contents, etc. */ 711 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 712 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 713 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 714 1.1 christos 715 1.1 christos /* Fix the opcode. */ 716 1.1 christos if (code == 0xe0) 717 1.1 christos bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2); 718 1.1 christos else if (code == 0xe1) 719 1.1 christos bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2); 720 1.1 christos 721 1.1 christos /* Fix the relocation's type. */ 722 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 723 1.1 christos R_MN10200_PCREL16); 724 1.1 christos 725 1.1 christos /* The opcode got shorter too, so we have to fix the offset. */ 726 1.1 christos irel->r_offset -= 1; 727 1.1 christos 728 1.1 christos /* Delete two bytes of data. */ 729 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec, 730 1.1 christos irel->r_offset + 1, 2)) 731 1.1 christos goto error_return; 732 1.1 christos 733 1.1 christos /* That will change things, so, we should relax again. 734 1.1.1.10 christos Note that this is not required, and it may be slow. */ 735 1.1 christos *again = true; 736 1.1 christos } 737 1.1 christos } 738 1.1 christos 739 1.1 christos /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative 740 1.1 christos branch. */ 741 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16) 742 1.1 christos { 743 1.1 christos bfd_vma value = symval; 744 1.1 christos 745 1.1 christos /* Deal with pc-relative gunk. */ 746 1.1 christos value -= (sec->output_section->vma + sec->output_offset); 747 1.1 christos value -= (irel->r_offset + 2); 748 1.1 christos value += irel->r_addend; 749 1.1 christos 750 1.1 christos /* See if the value will fit in 8 bits, note the high value is 751 1.1 christos 0x7f + 1 as the target will be one bytes closer if we are 752 1.1 christos able to relax. */ 753 1.1 christos if ((long) value < 0x80 && (long) value > -0x80) 754 1.1 christos { 755 1.1 christos unsigned char code; 756 1.1 christos 757 1.1 christos /* Get the opcode. */ 758 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1); 759 1.1 christos 760 1.1 christos if (code != 0xfc) 761 1.1 christos continue; 762 1.1 christos 763 1.1 christos /* Note that we've changed the relocs, section contents, etc. */ 764 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 765 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 766 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 767 1.1 christos 768 1.1 christos /* Fix the opcode. */ 769 1.1 christos bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1); 770 1.1 christos 771 1.1 christos /* Fix the relocation's type. */ 772 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 773 1.1 christos R_MN10200_PCREL8); 774 1.1 christos 775 1.1 christos /* Delete one byte of data. */ 776 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec, 777 1.1 christos irel->r_offset + 1, 1)) 778 1.1 christos goto error_return; 779 1.1 christos 780 1.1 christos /* That will change things, so, we should relax again. 781 1.1.1.10 christos Note that this is not required, and it may be slow. */ 782 1.1 christos *again = true; 783 1.1 christos } 784 1.1 christos } 785 1.1 christos 786 1.1 christos /* Try to eliminate an unconditional 8 bit pc-relative branch 787 1.1 christos which immediately follows a conditional 8 bit pc-relative 788 1.1 christos branch around the unconditional branch. 789 1.1 christos 790 1.1 christos original: new: 791 1.1 christos bCC lab1 bCC' lab2 792 1.1 christos bra lab2 793 1.1 christos lab1: lab1: 794 1.1 christos 795 1.1 christos This happens when the bCC can't reach lab2 at assembly time, 796 1.1 christos but due to other relaxations it can reach at link time. */ 797 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8) 798 1.1 christos { 799 1.1 christos Elf_Internal_Rela *nrel; 800 1.1 christos unsigned char code; 801 1.1 christos 802 1.1 christos /* Do nothing if this reloc is the last byte in the section. */ 803 1.1 christos if (irel->r_offset == sec->size) 804 1.1 christos continue; 805 1.1 christos 806 1.1 christos /* See if the next instruction is an unconditional pc-relative 807 1.1 christos branch, more often than not this test will fail, so we 808 1.1 christos test it first to speed things up. */ 809 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset + 1); 810 1.1 christos if (code != 0xea) 811 1.1 christos continue; 812 1.1 christos 813 1.1 christos /* Also make sure the next relocation applies to the next 814 1.1 christos instruction and that it's a pc-relative 8 bit branch. */ 815 1.1 christos nrel = irel + 1; 816 1.1 christos if (nrel == irelend 817 1.1 christos || irel->r_offset + 2 != nrel->r_offset 818 1.1 christos || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8) 819 1.1 christos continue; 820 1.1 christos 821 1.1 christos /* Make sure our destination immediately follows the 822 1.1 christos unconditional branch. */ 823 1.1 christos if (symval != (sec->output_section->vma + sec->output_offset 824 1.1 christos + irel->r_offset + 3)) 825 1.1 christos continue; 826 1.1 christos 827 1.1 christos /* Now make sure we are a conditional branch. This may not 828 1.1 christos be necessary, but why take the chance. 829 1.1 christos 830 1.1 christos Note these checks assume that R_MN10200_PCREL8 relocs 831 1.1 christos only occur on bCC and bCCx insns. If they occured 832 1.1 christos elsewhere, we'd need to know the start of this insn 833 1.1 christos for this check to be accurate. */ 834 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1); 835 1.1 christos if (code != 0xe0 && code != 0xe1 && code != 0xe2 836 1.1 christos && code != 0xe3 && code != 0xe4 && code != 0xe5 837 1.1 christos && code != 0xe6 && code != 0xe7 && code != 0xe8 838 1.1 christos && code != 0xe9 && code != 0xec && code != 0xed 839 1.1 christos && code != 0xee && code != 0xef && code != 0xfc 840 1.1 christos && code != 0xfd && code != 0xfe && code != 0xff) 841 1.1 christos continue; 842 1.1 christos 843 1.1 christos /* We also have to be sure there is no symbol/label 844 1.1 christos at the unconditional branch. */ 845 1.1 christos if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf, 846 1.1 christos irel->r_offset + 1)) 847 1.1 christos continue; 848 1.1 christos 849 1.1 christos /* Note that we've changed the relocs, section contents, etc. */ 850 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 851 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 852 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 853 1.1 christos 854 1.1 christos /* Reverse the condition of the first branch. */ 855 1.1 christos switch (code) 856 1.1 christos { 857 1.1 christos case 0xfc: 858 1.1 christos code = 0xfd; 859 1.1 christos break; 860 1.1 christos case 0xfd: 861 1.1 christos code = 0xfc; 862 1.1 christos break; 863 1.1 christos case 0xfe: 864 1.1 christos code = 0xff; 865 1.1 christos break; 866 1.1 christos case 0xff: 867 1.1 christos code = 0xfe; 868 1.1 christos break; 869 1.1 christos case 0xe8: 870 1.1 christos code = 0xe9; 871 1.1 christos break; 872 1.1 christos case 0xe9: 873 1.1 christos code = 0xe8; 874 1.1 christos break; 875 1.1 christos case 0xe0: 876 1.1 christos code = 0xe2; 877 1.1 christos break; 878 1.1 christos case 0xe2: 879 1.1 christos code = 0xe0; 880 1.1 christos break; 881 1.1 christos case 0xe3: 882 1.1 christos code = 0xe1; 883 1.1 christos break; 884 1.1 christos case 0xe1: 885 1.1 christos code = 0xe3; 886 1.1 christos break; 887 1.1 christos case 0xe4: 888 1.1 christos code = 0xe6; 889 1.1 christos break; 890 1.1 christos case 0xe6: 891 1.1 christos code = 0xe4; 892 1.1 christos break; 893 1.1 christos case 0xe7: 894 1.1 christos code = 0xe5; 895 1.1 christos break; 896 1.1 christos case 0xe5: 897 1.1 christos code = 0xe7; 898 1.1 christos break; 899 1.1 christos case 0xec: 900 1.1 christos code = 0xed; 901 1.1 christos break; 902 1.1 christos case 0xed: 903 1.1 christos code = 0xec; 904 1.1 christos break; 905 1.1 christos case 0xee: 906 1.1 christos code = 0xef; 907 1.1 christos break; 908 1.1 christos case 0xef: 909 1.1 christos code = 0xee; 910 1.1 christos break; 911 1.1 christos } 912 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 1); 913 1.1 christos 914 1.1 christos /* Set the reloc type and symbol for the first branch 915 1.1 christos from the second branch. */ 916 1.1 christos irel->r_info = nrel->r_info; 917 1.1 christos 918 1.1 christos /* Make the reloc for the second branch a null reloc. */ 919 1.1 christos nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info), 920 1.1 christos R_MN10200_NONE); 921 1.1 christos 922 1.1 christos /* Delete two bytes of data. */ 923 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec, 924 1.1 christos irel->r_offset + 1, 2)) 925 1.1 christos goto error_return; 926 1.1 christos 927 1.1 christos /* That will change things, so, we should relax again. 928 1.1.1.10 christos Note that this is not required, and it may be slow. */ 929 1.1 christos *again = true; 930 1.1 christos } 931 1.1 christos 932 1.1 christos /* Try to turn a 24bit immediate, displacement or absolute address 933 1.1 christos into a 16bit immediate, displacement or absolute address. */ 934 1.1 christos if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24) 935 1.1 christos { 936 1.1 christos bfd_vma value = symval; 937 1.1 christos 938 1.1 christos /* See if the value will fit in 16 bits. 939 1.1 christos We allow any 16bit match here. We prune those we can't 940 1.1 christos handle below. */ 941 1.1 christos if ((long) value < 0x7fff && (long) value > -0x8000) 942 1.1 christos { 943 1.1 christos unsigned char code; 944 1.1 christos 945 1.1 christos /* All insns which have 24bit operands are 5 bytes long, 946 1.1 christos the first byte will always be 0xf4, but we double check 947 1.1 christos it just in case. */ 948 1.1 christos 949 1.1 christos /* Get the first opcode. */ 950 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 2); 951 1.1 christos 952 1.1 christos if (code != 0xf4) 953 1.1 christos continue; 954 1.1 christos 955 1.1 christos /* Get the second opcode. */ 956 1.1 christos code = bfd_get_8 (abfd, contents + irel->r_offset - 1); 957 1.1 christos 958 1.1 christos switch (code & 0xfc) 959 1.1 christos { 960 1.1 christos /* mov imm24,dn -> mov imm16,dn */ 961 1.1 christos case 0x70: 962 1.1 christos /* Not safe if the high bit is on as relaxing may 963 1.1 christos move the value out of high mem and thus not fit 964 1.1 christos in a signed 16bit value. */ 965 1.1 christos if (value & 0x8000) 966 1.1 christos continue; 967 1.1 christos 968 1.1 christos /* Note that we've changed the relocation contents, etc. */ 969 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 970 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 971 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 972 1.1 christos 973 1.1 christos /* Fix the opcode. */ 974 1.1 christos bfd_put_8 (abfd, 0xf8 + (code & 0x03), 975 1.1 christos contents + irel->r_offset - 2); 976 1.1 christos 977 1.1 christos /* Fix the relocation's type. */ 978 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 979 1.1 christos R_MN10200_16); 980 1.1 christos 981 1.1 christos /* The opcode got shorter too, so we have to fix the 982 1.1 christos offset. */ 983 1.1 christos irel->r_offset -= 1; 984 1.1 christos 985 1.1 christos /* Delete two bytes of data. */ 986 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec, 987 1.1 christos irel->r_offset + 1, 2)) 988 1.1 christos goto error_return; 989 1.1 christos 990 1.1 christos /* That will change things, so, we should relax again. 991 1.1.1.10 christos Note that this is not required, and it may be slow. */ 992 1.1 christos *again = true; 993 1.1 christos break; 994 1.1 christos 995 1.1 christos /* mov imm24,an -> mov imm16,an 996 1.1 christos cmp imm24,an -> cmp imm16,an 997 1.1 christos mov (abs24),dn -> mov (abs16),dn 998 1.1 christos mov dn,(abs24) -> mov dn,(abs16) 999 1.1 christos movb dn,(abs24) -> movb dn,(abs16) 1000 1.1 christos movbu (abs24),dn -> movbu (abs16),dn */ 1001 1.1 christos case 0x74: 1002 1.1 christos case 0x7c: 1003 1.1 christos case 0xc0: 1004 1.1 christos case 0x40: 1005 1.1 christos case 0x44: 1006 1.1 christos case 0xc8: 1007 1.1 christos /* Note that we've changed the relocation contents, etc. */ 1008 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 1009 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 1010 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 1011 1.1 christos 1012 1.1 christos if ((code & 0xfc) == 0x74) 1013 1.1 christos code = 0xdc + (code & 0x03); 1014 1.1 christos else if ((code & 0xfc) == 0x7c) 1015 1.1 christos code = 0xec + (code & 0x03); 1016 1.1 christos else if ((code & 0xfc) == 0xc0) 1017 1.1 christos code = 0xc8 + (code & 0x03); 1018 1.1 christos else if ((code & 0xfc) == 0x40) 1019 1.1 christos code = 0xc0 + (code & 0x03); 1020 1.1 christos else if ((code & 0xfc) == 0x44) 1021 1.1 christos code = 0xc4 + (code & 0x03); 1022 1.1 christos else if ((code & 0xfc) == 0xc8) 1023 1.1 christos code = 0xcc + (code & 0x03); 1024 1.1 christos 1025 1.1 christos /* Fix the opcode. */ 1026 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 2); 1027 1.1 christos 1028 1.1 christos /* Fix the relocation's type. */ 1029 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1030 1.1 christos R_MN10200_16); 1031 1.1 christos 1032 1.1 christos /* The opcode got shorter too, so we have to fix the 1033 1.1 christos offset. */ 1034 1.1 christos irel->r_offset -= 1; 1035 1.1 christos 1036 1.1 christos /* Delete two bytes of data. */ 1037 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec, 1038 1.1 christos irel->r_offset + 1, 2)) 1039 1.1 christos goto error_return; 1040 1.1 christos 1041 1.1 christos /* That will change things, so, we should relax again. 1042 1.1.1.10 christos Note that this is not required, and it may be slow. */ 1043 1.1 christos *again = true; 1044 1.1 christos break; 1045 1.1 christos 1046 1.1 christos /* cmp imm24,dn -> cmp imm16,dn 1047 1.1 christos mov (abs24),an -> mov (abs16),an 1048 1.1 christos mov an,(abs24) -> mov an,(abs16) 1049 1.1 christos add imm24,dn -> add imm16,dn 1050 1.1 christos add imm24,an -> add imm16,an 1051 1.1 christos sub imm24,dn -> sub imm16,dn 1052 1.1 christos sub imm24,an -> sub imm16,an 1053 1.1 christos And all d24->d16 in memory ops. */ 1054 1.1 christos case 0x78: 1055 1.1 christos case 0xd0: 1056 1.1 christos case 0x50: 1057 1.1 christos case 0x60: 1058 1.1 christos case 0x64: 1059 1.1 christos case 0x68: 1060 1.1 christos case 0x6c: 1061 1.1 christos case 0x80: 1062 1.1 christos case 0xf0: 1063 1.1 christos case 0x00: 1064 1.1 christos case 0x10: 1065 1.1 christos case 0xb0: 1066 1.1 christos case 0x30: 1067 1.1 christos case 0xa0: 1068 1.1 christos case 0x20: 1069 1.1 christos case 0x90: 1070 1.1 christos /* Not safe if the high bit is on as relaxing may 1071 1.1 christos move the value out of high mem and thus not fit 1072 1.1 christos in a signed 16bit value. */ 1073 1.1 christos if (((code & 0xfc) == 0x78 1074 1.1 christos || (code & 0xfc) == 0x60 1075 1.1 christos || (code & 0xfc) == 0x64 1076 1.1 christos || (code & 0xfc) == 0x68 1077 1.1 christos || (code & 0xfc) == 0x6c 1078 1.1 christos || (code & 0xfc) == 0x80 1079 1.1 christos || (code & 0xfc) == 0xf0 1080 1.1 christos || (code & 0xfc) == 0x00 1081 1.1 christos || (code & 0xfc) == 0x10 1082 1.1 christos || (code & 0xfc) == 0xb0 1083 1.1 christos || (code & 0xfc) == 0x30 1084 1.1 christos || (code & 0xfc) == 0xa0 1085 1.1 christos || (code & 0xfc) == 0x20 1086 1.1 christos || (code & 0xfc) == 0x90) 1087 1.1 christos && (value & 0x8000) != 0) 1088 1.1 christos continue; 1089 1.1 christos 1090 1.1 christos /* Note that we've changed the relocation contents, etc. */ 1091 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 1092 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 1093 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 1094 1.1 christos 1095 1.1 christos /* Fix the opcode. */ 1096 1.1 christos bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2); 1097 1.1 christos 1098 1.1 christos if ((code & 0xfc) == 0x78) 1099 1.1 christos code = 0x48 + (code & 0x03); 1100 1.1 christos else if ((code & 0xfc) == 0xd0) 1101 1.1 christos code = 0x30 + (code & 0x03); 1102 1.1 christos else if ((code & 0xfc) == 0x50) 1103 1.1 christos code = 0x20 + (code & 0x03); 1104 1.1 christos else if ((code & 0xfc) == 0x60) 1105 1.1 christos code = 0x18 + (code & 0x03); 1106 1.1 christos else if ((code & 0xfc) == 0x64) 1107 1.1 christos code = 0x08 + (code & 0x03); 1108 1.1 christos else if ((code & 0xfc) == 0x68) 1109 1.1 christos code = 0x1c + (code & 0x03); 1110 1.1 christos else if ((code & 0xfc) == 0x6c) 1111 1.1 christos code = 0x0c + (code & 0x03); 1112 1.1 christos else if ((code & 0xfc) == 0x80) 1113 1.1 christos code = 0xc0 + (code & 0x07); 1114 1.1 christos else if ((code & 0xfc) == 0xf0) 1115 1.1 christos code = 0xb0 + (code & 0x07); 1116 1.1 christos else if ((code & 0xfc) == 0x00) 1117 1.1 christos code = 0x80 + (code & 0x07); 1118 1.1 christos else if ((code & 0xfc) == 0x10) 1119 1.1 christos code = 0xa0 + (code & 0x07); 1120 1.1 christos else if ((code & 0xfc) == 0xb0) 1121 1.1 christos code = 0x70 + (code & 0x07); 1122 1.1 christos else if ((code & 0xfc) == 0x30) 1123 1.1 christos code = 0x60 + (code & 0x07); 1124 1.1 christos else if ((code & 0xfc) == 0xa0) 1125 1.1 christos code = 0xd0 + (code & 0x07); 1126 1.1 christos else if ((code & 0xfc) == 0x20) 1127 1.1 christos code = 0x90 + (code & 0x07); 1128 1.1 christos else if ((code & 0xfc) == 0x90) 1129 1.1 christos code = 0x50 + (code & 0x07); 1130 1.1 christos 1131 1.1 christos bfd_put_8 (abfd, code, contents + irel->r_offset - 1); 1132 1.1 christos 1133 1.1 christos /* Fix the relocation's type. */ 1134 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1135 1.1 christos R_MN10200_16); 1136 1.1 christos 1137 1.1 christos /* Delete one bytes of data. */ 1138 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec, 1139 1.1 christos irel->r_offset + 2, 1)) 1140 1.1 christos goto error_return; 1141 1.1 christos 1142 1.1 christos /* That will change things, so, we should relax again. 1143 1.1.1.10 christos Note that this is not required, and it may be slow. */ 1144 1.1 christos *again = true; 1145 1.1 christos break; 1146 1.1 christos 1147 1.1 christos /* movb (abs24),dn ->movbu (abs16),dn extxb bn */ 1148 1.1 christos case 0xc4: 1149 1.1 christos /* Note that we've changed the reldection contents, etc. */ 1150 1.1 christos elf_section_data (sec)->relocs = internal_relocs; 1151 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 1152 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 1153 1.1 christos 1154 1.1 christos bfd_put_8 (abfd, 0xcc + (code & 0x03), 1155 1.1 christos contents + irel->r_offset - 2); 1156 1.1 christos 1157 1.1 christos bfd_put_8 (abfd, 0xb8 + (code & 0x03), 1158 1.1 christos contents + irel->r_offset - 1); 1159 1.1 christos 1160 1.1 christos /* Fix the relocation's type. */ 1161 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1162 1.1 christos R_MN10200_16); 1163 1.1 christos 1164 1.1 christos /* The reloc will be applied one byte in front of its 1165 1.1 christos current location. */ 1166 1.1 christos irel->r_offset -= 1; 1167 1.1 christos 1168 1.1 christos /* Delete one bytes of data. */ 1169 1.1 christos if (!mn10200_elf_relax_delete_bytes (abfd, sec, 1170 1.1 christos irel->r_offset + 2, 1)) 1171 1.1 christos goto error_return; 1172 1.1 christos 1173 1.1 christos /* That will change things, so, we should relax again. 1174 1.1.1.10 christos Note that this is not required, and it may be slow. */ 1175 1.1 christos *again = true; 1176 1.1 christos break; 1177 1.1 christos } 1178 1.1 christos } 1179 1.1 christos } 1180 1.1 christos } 1181 1.1 christos 1182 1.1 christos if (isymbuf != NULL 1183 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf) 1184 1.1 christos { 1185 1.1 christos if (! link_info->keep_memory) 1186 1.1 christos free (isymbuf); 1187 1.1 christos else 1188 1.1 christos { 1189 1.1 christos /* Cache the symbols for elf_link_input_bfd. */ 1190 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 1191 1.1 christos } 1192 1.1 christos } 1193 1.1 christos 1194 1.1 christos if (contents != NULL 1195 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents) 1196 1.1 christos { 1197 1.1 christos if (! link_info->keep_memory) 1198 1.1 christos free (contents); 1199 1.1 christos else 1200 1.1 christos { 1201 1.1 christos /* Cache the section contents for elf_link_input_bfd. */ 1202 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 1203 1.1 christos } 1204 1.1 christos } 1205 1.1.1.9 christos 1206 1.1 christos if (elf_section_data (sec)->relocs != internal_relocs) 1207 1.1 christos free (internal_relocs); 1208 1.1.1.10 christos 1209 1.1 christos return true; 1210 1.1 christos 1211 1.1.1.9 christos error_return: 1212 1.1 christos if (symtab_hdr->contents != (unsigned char *) isymbuf) 1213 1.1.1.9 christos free (isymbuf); 1214 1.1 christos if (elf_section_data (sec)->this_hdr.contents != contents) 1215 1.1.1.9 christos free (contents); 1216 1.1 christos if (elf_section_data (sec)->relocs != internal_relocs) 1217 1.1 christos free (internal_relocs); 1218 1.1.1.10 christos 1219 1.1 christos return false; 1220 1.1 christos } 1221 1.1 christos 1222 1.1 christos /* Return TRUE if a symbol exists at the given address, else return 1223 1.1.1.10 christos FALSE. */ 1224 1.1.1.2 christos static bool 1225 1.1.1.2 christos mn10200_elf_symbol_address_p (bfd *abfd, 1226 1.1.1.2 christos asection *sec, 1227 1.1.1.2 christos Elf_Internal_Sym *isym, 1228 1.1 christos bfd_vma addr) 1229 1.1 christos { 1230 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1231 1.1 christos unsigned int sec_shndx; 1232 1.1 christos Elf_Internal_Sym *isymend; 1233 1.1 christos struct elf_link_hash_entry **sym_hashes; 1234 1.1 christos struct elf_link_hash_entry **end_hashes; 1235 1.1 christos unsigned int symcount; 1236 1.1 christos 1237 1.1 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 1238 1.1 christos 1239 1.1 christos /* Examine all the local symbols. */ 1240 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1241 1.1 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 1242 1.1 christos { 1243 1.1 christos if (isym->st_shndx == sec_shndx 1244 1.1.1.10 christos && isym->st_value == addr) 1245 1.1 christos return true; 1246 1.1 christos } 1247 1.1 christos 1248 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 1249 1.1 christos - symtab_hdr->sh_info); 1250 1.1 christos sym_hashes = elf_sym_hashes (abfd); 1251 1.1 christos end_hashes = sym_hashes + symcount; 1252 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++) 1253 1.1 christos { 1254 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 1255 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined 1256 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak) 1257 1.1 christos && sym_hash->root.u.def.section == sec 1258 1.1.1.10 christos && sym_hash->root.u.def.value == addr) 1259 1.1 christos return true; 1260 1.1 christos } 1261 1.1.1.10 christos 1262 1.1 christos return false; 1263 1.1 christos } 1264 1.1 christos 1265 1.1 christos /* This is a version of bfd_generic_get_relocated_section_contents 1266 1.1 christos which uses mn10200_elf_relocate_section. */ 1267 1.1 christos 1268 1.1.1.2 christos static bfd_byte * 1269 1.1.1.2 christos mn10200_elf_get_relocated_section_contents (bfd *output_bfd, 1270 1.1.1.2 christos struct bfd_link_info *link_info, 1271 1.1.1.2 christos struct bfd_link_order *link_order, 1272 1.1.1.10 christos bfd_byte *data, 1273 1.1.1.2 christos bool relocatable, 1274 1.1 christos asymbol **symbols) 1275 1.1 christos { 1276 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1277 1.1 christos asection *input_section = link_order->u.indirect.section; 1278 1.1 christos bfd *input_bfd = input_section->owner; 1279 1.1 christos asection **sections = NULL; 1280 1.1 christos Elf_Internal_Rela *internal_relocs = NULL; 1281 1.1 christos Elf_Internal_Sym *isymbuf = NULL; 1282 1.1 christos 1283 1.1 christos /* We only need to handle the case of relaxing, or of having a 1284 1.1 christos particular set of section contents, specially. */ 1285 1.1 christos if (relocatable 1286 1.1 christos || elf_section_data (input_section)->this_hdr.contents == NULL) 1287 1.1 christos return bfd_generic_get_relocated_section_contents (output_bfd, link_info, 1288 1.1 christos link_order, data, 1289 1.1 christos relocatable, 1290 1.1 christos symbols); 1291 1.1 christos 1292 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 1293 1.1.1.10 christos 1294 1.1.1.10 christos bfd_byte *orig_data = data; 1295 1.1.1.10 christos if (data == NULL) 1296 1.1.1.10 christos { 1297 1.1.1.10 christos data = bfd_malloc (input_section->size); 1298 1.1.1.10 christos if (data == NULL) 1299 1.1.1.10 christos return NULL; 1300 1.1 christos } 1301 1.1 christos memcpy (data, elf_section_data (input_section)->this_hdr.contents, 1302 1.1 christos (size_t) input_section->size); 1303 1.1 christos 1304 1.1 christos if ((input_section->flags & SEC_RELOC) != 0 1305 1.1 christos && input_section->reloc_count > 0) 1306 1.1 christos { 1307 1.1 christos Elf_Internal_Sym *isym; 1308 1.1 christos Elf_Internal_Sym *isymend; 1309 1.1 christos asection **secpp; 1310 1.1 christos bfd_size_type amt; 1311 1.1 christos 1312 1.1.1.2 christos internal_relocs = (_bfd_elf_link_read_relocs 1313 1.1.1.10 christos (input_bfd, input_section, NULL, 1314 1.1 christos (Elf_Internal_Rela *) NULL, false)); 1315 1.1 christos if (internal_relocs == NULL) 1316 1.1 christos goto error_return; 1317 1.1 christos 1318 1.1 christos if (symtab_hdr->sh_info != 0) 1319 1.1 christos { 1320 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1321 1.1 christos if (isymbuf == NULL) 1322 1.1 christos isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, 1323 1.1 christos symtab_hdr->sh_info, 0, 1324 1.1 christos NULL, NULL, NULL); 1325 1.1 christos if (isymbuf == NULL) 1326 1.1 christos goto error_return; 1327 1.1 christos } 1328 1.1 christos 1329 1.1 christos amt = symtab_hdr->sh_info; 1330 1.1 christos amt *= sizeof (asection *); 1331 1.1 christos sections = (asection **) bfd_malloc (amt); 1332 1.1 christos if (sections == NULL && amt != 0) 1333 1.1 christos goto error_return; 1334 1.1 christos 1335 1.1 christos isymend = isymbuf + symtab_hdr->sh_info; 1336 1.1 christos for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp) 1337 1.1 christos { 1338 1.1 christos asection *isec; 1339 1.1 christos 1340 1.1 christos if (isym->st_shndx == SHN_UNDEF) 1341 1.1 christos isec = bfd_und_section_ptr; 1342 1.1 christos else if (isym->st_shndx == SHN_ABS) 1343 1.1 christos isec = bfd_abs_section_ptr; 1344 1.1 christos else if (isym->st_shndx == SHN_COMMON) 1345 1.1 christos isec = bfd_com_section_ptr; 1346 1.1 christos else 1347 1.1 christos isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 1348 1.1 christos 1349 1.1 christos *secpp = isec; 1350 1.1 christos } 1351 1.1 christos 1352 1.1 christos if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd, 1353 1.1 christos input_section, data, internal_relocs, 1354 1.1 christos isymbuf, sections)) 1355 1.1 christos goto error_return; 1356 1.1.1.9 christos 1357 1.1.1.9 christos free (sections); 1358 1.1 christos if (symtab_hdr->contents != (unsigned char *) isymbuf) 1359 1.1 christos free (isymbuf); 1360 1.1 christos if (elf_section_data (input_section)->relocs != internal_relocs) 1361 1.1 christos free (internal_relocs); 1362 1.1 christos } 1363 1.1 christos 1364 1.1 christos return data; 1365 1.1 christos 1366 1.1.1.9 christos error_return: 1367 1.1.1.9 christos free (sections); 1368 1.1 christos if (symtab_hdr->contents != (unsigned char *) isymbuf) 1369 1.1.1.9 christos free (isymbuf); 1370 1.1 christos if (elf_section_data (input_section)->relocs != internal_relocs) 1371 1.1.1.10 christos free (internal_relocs); 1372 1.1.1.10 christos if (orig_data == NULL) 1373 1.1 christos free (data); 1374 1.1 christos return NULL; 1375 1.1 christos } 1376 1.1.1.4 christos 1377 1.1 christos #define TARGET_LITTLE_SYM mn10200_elf32_vec 1378 1.1 christos #define TARGET_LITTLE_NAME "elf32-mn10200" 1379 1.1 christos #define ELF_ARCH bfd_arch_mn10200 1380 1.1 christos #define ELF_MACHINE_CODE EM_MN10200 1381 1.1 christos #define ELF_MACHINE_ALT1 EM_CYGNUS_MN10200 1382 1.1 christos #define ELF_MAXPAGESIZE 0x1000 1383 1.1 christos 1384 1.1 christos #define elf_backend_rela_normal 1 1385 1.1.1.8 christos #define elf_info_to_howto mn10200_info_to_howto 1386 1.1 christos #define elf_info_to_howto_rel NULL 1387 1.1 christos #define elf_backend_relocate_section mn10200_elf_relocate_section 1388 1.1 christos #define bfd_elf32_bfd_relax_section mn10200_elf_relax_section 1389 1.1 christos #define bfd_elf32_bfd_get_relocated_section_contents \ 1390 1.1 christos mn10200_elf_get_relocated_section_contents 1391 1.1 christos 1392 1.1 christos #define elf_symbol_leading_char '_' 1393 1.1 christos 1394 #include "elf32-target.h" 1395