1 1.1 christos /* Morpho Technologies MT specific support for 32-bit ELF 2 1.10 christos Copyright (C) 2001-2025 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.6 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 1.6 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 #include "elf/mt.h" 26 1.1 christos 27 1.1 christos /* Prototypes. */ 28 1.3 christos static reloc_howto_type * mt_reloc_type_lookup 29 1.1 christos (bfd *, bfd_reloc_code_real_type); 30 1.1 christos 31 1.8 christos static bool mt_info_to_howto_rela 32 1.1 christos (bfd *, arelent *, Elf_Internal_Rela *); 33 1.1 christos 34 1.1 christos static bfd_reloc_status_type mt_elf_relocate_hi16 35 1.1 christos (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma); 36 1.1 christos 37 1.1 christos static bfd_reloc_status_type mt_final_link_relocate 38 1.3 christos (reloc_howto_type *, bfd *, asection *, bfd_byte *, 39 1.1 christos Elf_Internal_Rela *, bfd_vma); 40 1.1 christos 41 1.8 christos static int mt_elf_relocate_section 42 1.3 christos (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 43 1.1 christos Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); 44 1.1 christos 45 1.1 christos /* Relocation tables. */ 46 1.1 christos static reloc_howto_type mt_elf_howto_table [] = 47 1.1 christos { 48 1.1 christos /* This reloc does nothing. */ 49 1.6 christos HOWTO (R_MT_NONE, /* type */ 50 1.6 christos 0, /* rightshift */ 51 1.8 christos 0, /* size */ 52 1.6 christos 0, /* bitsize */ 53 1.8 christos false, /* pc_relative */ 54 1.6 christos 0, /* bitpos */ 55 1.6 christos complain_overflow_dont, /* complain_on_overflow */ 56 1.6 christos bfd_elf_generic_reloc, /* special_function */ 57 1.6 christos "R_MT_NONE", /* name */ 58 1.8 christos false, /* partial_inplace */ 59 1.6 christos 0 , /* src_mask */ 60 1.6 christos 0, /* dst_mask */ 61 1.8 christos false), /* pcrel_offset */ 62 1.1 christos 63 1.1 christos /* A 16 bit absolute relocation. */ 64 1.6 christos HOWTO (R_MT_16, /* type */ 65 1.6 christos 0, /* rightshift */ 66 1.8 christos 4, /* size */ 67 1.6 christos 16, /* bitsize */ 68 1.8 christos false, /* pc_relative */ 69 1.6 christos 0, /* bitpos */ 70 1.6 christos complain_overflow_dont, /* complain_on_overflow */ 71 1.6 christos bfd_elf_generic_reloc, /* special_function */ 72 1.6 christos "R_MT_16", /* name */ 73 1.8 christos false, /* partial_inplace */ 74 1.6 christos 0 , /* src_mask */ 75 1.6 christos 0xffff, /* dst_mask */ 76 1.8 christos false), /* pcrel_offset */ 77 1.1 christos 78 1.1 christos /* A 32 bit absolute relocation. */ 79 1.6 christos HOWTO (R_MT_32, /* type */ 80 1.6 christos 0, /* rightshift */ 81 1.8 christos 4, /* size */ 82 1.6 christos 32, /* bitsize */ 83 1.8 christos false, /* pc_relative */ 84 1.6 christos 0, /* bitpos */ 85 1.6 christos complain_overflow_dont, /* complain_on_overflow */ 86 1.6 christos bfd_elf_generic_reloc, /* special_function */ 87 1.6 christos "R_MT_32", /* name */ 88 1.8 christos false, /* partial_inplace */ 89 1.6 christos 0 , /* src_mask */ 90 1.6 christos 0xffffffff, /* dst_mask */ 91 1.8 christos false), /* pcrel_offset */ 92 1.1 christos 93 1.1 christos /* A 32 bit pc-relative relocation. */ 94 1.6 christos HOWTO (R_MT_32_PCREL, /* type */ 95 1.6 christos 0, /* rightshift */ 96 1.8 christos 4, /* size */ 97 1.6 christos 32, /* bitsize */ 98 1.8 christos true, /* pc_relative */ 99 1.6 christos 0, /* bitpos */ 100 1.6 christos complain_overflow_dont, /* complain_on_overflow */ 101 1.6 christos bfd_elf_generic_reloc, /* special_function */ 102 1.6 christos "R_MT_32_PCREL", /* name */ 103 1.8 christos false, /* partial_inplace */ 104 1.6 christos 0 , /* src_mask */ 105 1.6 christos 0xffffffff, /* dst_mask */ 106 1.8 christos true), /* pcrel_offset */ 107 1.1 christos 108 1.1 christos /* A 16 bit pc-relative relocation. */ 109 1.6 christos HOWTO (R_MT_PC16, /* type */ 110 1.6 christos 0, /* rightshift */ 111 1.8 christos 4, /* size */ 112 1.6 christos 16, /* bitsize */ 113 1.8 christos true, /* pc_relative */ 114 1.6 christos 0, /* bitpos */ 115 1.6 christos complain_overflow_signed, /* complain_on_overflow */ 116 1.6 christos bfd_elf_generic_reloc, /* special_function */ 117 1.6 christos "R_MT_PC16", /* name */ 118 1.8 christos false, /* partial_inplace */ 119 1.6 christos 0, /* src_mask */ 120 1.6 christos 0xffff, /* dst_mask */ 121 1.8 christos true), /* pcrel_offset */ 122 1.1 christos 123 1.1 christos /* high 16 bits of symbol value. */ 124 1.6 christos HOWTO (R_MT_HI16, /* type */ 125 1.6 christos 0, /* rightshift */ 126 1.8 christos 4, /* size */ 127 1.6 christos 16, /* bitsize */ 128 1.8 christos false, /* pc_relative */ 129 1.6 christos 0, /* bitpos */ 130 1.6 christos complain_overflow_dont, /* complain_on_overflow */ 131 1.6 christos bfd_elf_generic_reloc, /* special_function */ 132 1.6 christos "R_MT_HI16", /* name */ 133 1.8 christos false, /* partial_inplace */ 134 1.6 christos 0xffff0000, /* src_mask */ 135 1.6 christos 0xffff0000, /* dst_mask */ 136 1.8 christos false), /* pcrel_offset */ 137 1.1 christos 138 1.1 christos /* Low 16 bits of symbol value. */ 139 1.6 christos HOWTO (R_MT_LO16, /* type */ 140 1.6 christos 0, /* rightshift */ 141 1.8 christos 4, /* size */ 142 1.6 christos 16, /* bitsize */ 143 1.8 christos false, /* pc_relative */ 144 1.6 christos 0, /* bitpos */ 145 1.6 christos complain_overflow_dont, /* complain_on_overflow */ 146 1.6 christos bfd_elf_generic_reloc, /* special_function */ 147 1.6 christos "R_MT_LO16", /* name */ 148 1.8 christos false, /* partial_inplace */ 149 1.6 christos 0xffff, /* src_mask */ 150 1.6 christos 0xffff, /* dst_mask */ 151 1.8 christos false), /* pcrel_offset */ 152 1.1 christos }; 153 1.1 christos 154 1.1 christos /* Map BFD reloc types to MT ELF reloc types. */ 155 1.1 christos 156 1.1 christos static reloc_howto_type * 157 1.1 christos mt_reloc_type_lookup 158 1.6 christos (bfd * abfd ATTRIBUTE_UNUSED, 159 1.1 christos bfd_reloc_code_real_type code) 160 1.1 christos { 161 1.1 christos /* Note that the mt_elf_howto_table is indxed by the R_ 162 1.1 christos constants. Thus, the order that the howto records appear in the 163 1.1 christos table *must* match the order of the relocation types defined in 164 1.1 christos include/elf/mt.h. */ 165 1.1 christos 166 1.1 christos switch (code) 167 1.1 christos { 168 1.1 christos case BFD_RELOC_NONE: 169 1.1 christos return &mt_elf_howto_table[ (int) R_MT_NONE]; 170 1.1 christos case BFD_RELOC_16: 171 1.1 christos return &mt_elf_howto_table[ (int) R_MT_16]; 172 1.1 christos case BFD_RELOC_32: 173 1.1 christos return &mt_elf_howto_table[ (int) R_MT_32]; 174 1.1 christos case BFD_RELOC_32_PCREL: 175 1.1 christos return &mt_elf_howto_table[ (int) R_MT_32_PCREL]; 176 1.1 christos case BFD_RELOC_16_PCREL: 177 1.1 christos return &mt_elf_howto_table[ (int) R_MT_PC16]; 178 1.1 christos case BFD_RELOC_HI16: 179 1.1 christos return &mt_elf_howto_table[ (int) R_MT_HI16]; 180 1.1 christos case BFD_RELOC_LO16: 181 1.1 christos return &mt_elf_howto_table[ (int) R_MT_LO16]; 182 1.1 christos 183 1.1 christos default: 184 1.1 christos /* Pacify gcc -Wall. */ 185 1.1 christos return NULL; 186 1.1 christos } 187 1.1 christos return NULL; 188 1.1 christos } 189 1.1 christos 190 1.1 christos static reloc_howto_type * 191 1.1 christos mt_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 192 1.1 christos const char *r_name) 193 1.1 christos { 194 1.1 christos unsigned int i; 195 1.1 christos 196 1.1 christos for (i = 0; 197 1.1 christos i < sizeof (mt_elf_howto_table) / sizeof (mt_elf_howto_table[0]); 198 1.1 christos i++) 199 1.1 christos if (mt_elf_howto_table[i].name != NULL 200 1.1 christos && strcasecmp (mt_elf_howto_table[i].name, r_name) == 0) 201 1.1 christos return &mt_elf_howto_table[i]; 202 1.1 christos 203 1.1 christos return NULL; 204 1.1 christos } 205 1.1 christos 206 1.1 christos bfd_reloc_status_type 207 1.1 christos mt_elf_relocate_hi16 208 1.6 christos (bfd * input_bfd, 209 1.1 christos Elf_Internal_Rela * relhi, 210 1.6 christos bfd_byte * contents, 211 1.6 christos bfd_vma value) 212 1.1 christos { 213 1.1 christos bfd_vma insn; 214 1.1 christos 215 1.1 christos insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); 216 1.1 christos 217 1.1 christos value += relhi->r_addend; 218 1.1 christos value >>= 16; 219 1.1 christos insn = ((insn & ~0xFFFF) | value); 220 1.1 christos 221 1.1 christos bfd_put_32 (input_bfd, insn, contents + relhi->r_offset); 222 1.1 christos return bfd_reloc_ok; 223 1.1 christos } 224 1.1 christos 225 1.1 christos /* XXX: The following code is the result of a cut&paste. This unfortunate 227 1.1 christos practice is very widespread in the various target back-end files. */ 228 1.1 christos 229 1.1 christos /* Set the howto pointer for a MT ELF reloc. */ 230 1.8 christos 231 1.8 christos static bool 232 1.8 christos mt_info_to_howto_rela (bfd *abfd, 233 1.8 christos arelent *cache_ptr, 234 1.1 christos Elf_Internal_Rela *dst) 235 1.1 christos { 236 1.1 christos unsigned int r_type; 237 1.1 christos 238 1.3 christos r_type = ELF32_R_TYPE (dst->r_info); 239 1.3 christos if (r_type >= (unsigned int) R_MT_max) 240 1.6 christos { 241 1.6 christos /* xgettext:c-format */ 242 1.6 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 243 1.6 christos abfd, r_type); 244 1.8 christos bfd_set_error (bfd_error_bad_value); 245 1.3 christos return false; 246 1.1 christos } 247 1.8 christos cache_ptr->howto = & mt_elf_howto_table [r_type]; 248 1.1 christos return true; 249 1.1 christos } 250 1.1 christos 251 1.1 christos /* Perform a single relocation. By default we use the standard BFD 252 1.1 christos routines. */ 253 1.1 christos 254 1.1 christos static bfd_reloc_status_type 255 1.6 christos mt_final_link_relocate 256 1.6 christos (reloc_howto_type * howto, 257 1.6 christos bfd * input_bfd, 258 1.6 christos asection * input_section, 259 1.1 christos bfd_byte * contents, 260 1.6 christos Elf_Internal_Rela * rel, 261 1.1 christos bfd_vma relocation) 262 1.1 christos { 263 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section, 264 1.1 christos contents, rel->r_offset, 265 1.1 christos relocation, rel->r_addend); 266 1.1 christos } 267 1.1 christos 268 1.1 christos /* Relocate a MT ELF section. 269 1.1 christos There is some attempt to make this function usable for many architectures, 270 1.1 christos both USE_REL and USE_RELA ['twould be nice if such a critter existed], 271 1.1 christos if only to serve as a learning tool. 272 1.1 christos 273 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker 274 1.1 christos to handle the relocations for a section. 275 1.1 christos 276 1.1 christos The relocs are always passed as Rela structures; if the section 277 1.1 christos actually uses Rel structures, the r_addend field will always be 278 1.1 christos zero. 279 1.1 christos 280 1.1 christos This function is responsible for adjusting the section contents as 281 1.1 christos necessary, and (if using Rela relocs and generating a relocatable 282 1.1 christos output file) adjusting the reloc addend as necessary. 283 1.1 christos 284 1.1 christos This function does not have to worry about setting the reloc 285 1.1 christos address or the reloc symbol index. 286 1.1 christos 287 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols. 288 1.1 christos 289 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file 290 1.1 christos corresponding to the st_shndx field of each local symbol. 291 1.1 christos 292 1.1 christos The global hash table entry for the global symbols can be found 293 1.1 christos via elf_sym_hashes (input_bfd). 294 1.1 christos 295 1.1 christos When generating relocatable output, this function must handle 296 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is 297 1.1 christos going to be the section symbol corresponding to the output 298 1.1 christos section, which means that the addend must be adjusted 299 1.1 christos accordingly. */ 300 1.8 christos 301 1.1 christos static int 302 1.6 christos mt_elf_relocate_section 303 1.1 christos (bfd * output_bfd ATTRIBUTE_UNUSED, 304 1.6 christos struct bfd_link_info * info, 305 1.6 christos bfd * input_bfd, 306 1.6 christos asection * input_section, 307 1.1 christos bfd_byte * contents, 308 1.6 christos Elf_Internal_Rela * relocs, 309 1.6 christos Elf_Internal_Sym * local_syms, 310 1.1 christos asection ** local_sections) 311 1.6 christos { 312 1.1 christos Elf_Internal_Shdr * symtab_hdr; 313 1.6 christos struct elf_link_hash_entry ** sym_hashes; 314 1.6 christos Elf_Internal_Rela * rel; 315 1.1 christos Elf_Internal_Rela * relend; 316 1.1 christos 317 1.1 christos symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 318 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 319 1.1 christos relend = relocs + input_section->reloc_count; 320 1.1 christos 321 1.1 christos for (rel = relocs; rel < relend; rel ++) 322 1.6 christos { 323 1.6 christos reloc_howto_type * howto; 324 1.6 christos unsigned long r_symndx; 325 1.6 christos Elf_Internal_Sym * sym; 326 1.1 christos asection * sec; 327 1.6 christos struct elf_link_hash_entry * h; 328 1.6 christos bfd_vma relocation; 329 1.6 christos bfd_reloc_status_type r; 330 1.6 christos const char * name = NULL; 331 1.3 christos int r_type; 332 1.1 christos 333 1.1 christos r_type = ELF32_R_TYPE (rel->r_info); 334 1.1 christos 335 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 336 1.1 christos 337 1.1 christos howto = mt_elf_howto_table + ELF32_R_TYPE (rel->r_info); 338 1.1 christos h = NULL; 339 1.1 christos sym = NULL; 340 1.3 christos sec = NULL; 341 1.1 christos 342 1.1 christos if (r_symndx < symtab_hdr->sh_info) 343 1.1 christos { 344 1.1 christos sym = local_syms + r_symndx; 345 1.1 christos sec = local_sections [r_symndx]; 346 1.3 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 347 1.1 christos 348 1.1 christos name = bfd_elf_string_from_elf_section 349 1.7 christos (input_bfd, symtab_hdr->sh_link, sym->st_name); 350 1.1 christos name = name == NULL ? bfd_section_name (sec) : name; 351 1.1 christos } 352 1.1 christos else 353 1.8 christos { 354 1.8 christos bool unresolved_reloc; 355 1.1 christos bool warned, ignored; 356 1.1 christos 357 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 358 1.1 christos r_symndx, symtab_hdr, sym_hashes, 359 1.3 christos h, sec, relocation, 360 1.1 christos unresolved_reloc, warned, ignored); 361 1.1 christos 362 1.1 christos name = h->root.root.string; 363 1.1 christos } 364 1.1 christos 365 1.1 christos if (sec != NULL && discarded_section (sec)) 366 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 367 1.1 christos rel, 1, relend, howto, 0, contents); 368 1.3 christos 369 1.1 christos if (bfd_link_relocatable (info)) 370 1.1 christos continue; 371 1.1 christos 372 1.1 christos /* Finally, the sole MT-specific part. */ 373 1.6 christos switch (r_type) 374 1.6 christos { 375 1.6 christos case R_MT_HI16: 376 1.6 christos r = mt_elf_relocate_hi16 (input_bfd, rel, contents, relocation); 377 1.1 christos break; 378 1.6 christos default: 379 1.6 christos r = mt_final_link_relocate (howto, input_bfd, input_section, 380 1.6 christos contents, rel, relocation); 381 1.6 christos break; 382 1.1 christos } 383 1.1 christos 384 1.1 christos 385 1.1 christos if (r != bfd_reloc_ok) 386 1.1 christos { 387 1.1 christos const char * msg = (const char *) NULL; 388 1.1 christos 389 1.1 christos switch (r) 390 1.1 christos { 391 1.5 christos case bfd_reloc_overflow: 392 1.1 christos (*info->callbacks->reloc_overflow) 393 1.1 christos (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, 394 1.1 christos input_bfd, input_section, rel->r_offset); 395 1.3 christos break; 396 1.1 christos 397 1.5 christos case bfd_reloc_undefined: 398 1.8 christos (*info->callbacks->undefined_symbol) 399 1.1 christos (info, name, input_bfd, input_section, rel->r_offset, true); 400 1.3 christos break; 401 1.1 christos 402 1.1 christos case bfd_reloc_outofrange: 403 1.1 christos msg = _("internal error: out of range error"); 404 1.1 christos break; 405 1.1 christos 406 1.1 christos case bfd_reloc_dangerous: 407 1.1 christos msg = _("internal error: dangerous relocation"); 408 1.1 christos break; 409 1.1 christos 410 1.1 christos default: 411 1.1 christos msg = _("internal error: unknown error"); 412 1.1 christos break; 413 1.1 christos } 414 1.1 christos 415 1.5 christos if (msg) 416 1.5 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 417 1.1 christos input_section, rel->r_offset); 418 1.1 christos } 419 1.1 christos } 420 1.8 christos 421 1.1 christos return true; 422 1.1 christos } 423 1.1 christos 424 1.1 christos /* Look through the relocs for a section during the first phase. 425 1.1 christos Since we don't do .gots or .plts, we just need to consider the 426 1.3 christos virtual table relocs for gc. */ 427 1.8 christos 428 1.8 christos static bool 429 1.8 christos mt_elf_check_relocs (bfd *abfd, 430 1.8 christos struct bfd_link_info *info, 431 1.8 christos asection *sec, 432 1.8 christos const Elf_Internal_Rela *relocs) 433 1.8 christos { 434 1.8 christos Elf_Internal_Shdr *symtab_hdr; 435 1.8 christos struct elf_link_hash_entry **sym_hashes; 436 1.8 christos const Elf_Internal_Rela *rel; 437 1.3 christos const Elf_Internal_Rela *rel_end; 438 1.3 christos 439 1.8 christos if (bfd_link_relocatable (info)) 440 1.3 christos return true; 441 1.1 christos 442 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 443 1.3 christos sym_hashes = elf_sym_hashes (abfd); 444 1.1 christos 445 1.1 christos rel_end = relocs + sec->reloc_count; 446 1.1 christos for (rel = relocs; rel < rel_end; rel++) 447 1.1 christos { 448 1.1 christos struct elf_link_hash_entry *h; 449 1.3 christos unsigned long r_symndx; 450 1.1 christos 451 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 452 1.6 christos if (r_symndx < symtab_hdr->sh_info) 453 1.1 christos h = NULL; 454 1.1 christos else 455 1.1 christos { 456 1.1 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 457 1.1 christos while (h->root.type == bfd_link_hash_indirect 458 1.1 christos || h->root.type == bfd_link_hash_warning) 459 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 460 1.1 christos } 461 1.1 christos } 462 1.8 christos 463 1.1 christos return true; 464 1.1 christos } 465 1.1 christos 466 1.1 christos /* Return the MACH for an e_flags value. */ 467 1.1 christos 468 1.1 christos static int 469 1.1 christos elf32_mt_machine (bfd *abfd) 470 1.1 christos { 471 1.1 christos switch (elf_elfheader (abfd)->e_flags & EF_MT_CPU_MASK) 472 1.1 christos { 473 1.1 christos case EF_MT_CPU_MRISC: return bfd_mach_ms1; 474 1.1 christos case EF_MT_CPU_MRISC2: return bfd_mach_mrisc2; 475 1.1 christos case EF_MT_CPU_MS2: return bfd_mach_ms2; 476 1.1 christos } 477 1.1 christos 478 1.1 christos return bfd_mach_ms1; 479 1.1 christos } 480 1.8 christos 481 1.8 christos static bool 482 1.1 christos mt_elf_object_p (bfd *abfd) 483 1.1 christos { 484 1.1 christos bfd_default_set_arch_mach (abfd, bfd_arch_mt, elf32_mt_machine (abfd)); 485 1.8 christos 486 1.1 christos return true; 487 1.1 christos } 488 1.1 christos 489 1.1 christos /* Function to set the ELF flag bits. */ 490 1.8 christos 491 1.8 christos static bool 492 1.1 christos mt_elf_set_private_flags (bfd *abfd, flagword flags) 493 1.1 christos { 494 1.8 christos elf_elfheader (abfd)->e_flags = flags; 495 1.8 christos elf_flags_init (abfd) = true; 496 1.1 christos return true; 497 1.1 christos } 498 1.1 christos 499 1.1 christos /* Merge backend specific data from an object file to the output 500 1.1 christos object file when linking. */ 501 1.8 christos 502 1.6 christos static bool 503 1.1 christos mt_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 504 1.6 christos { 505 1.8 christos bfd *obfd = info->output_bfd; 506 1.8 christos flagword old_flags, new_flags; 507 1.1 christos bool ok = true; 508 1.1 christos 509 1.6 christos /* Check if we have the same endianness. */ 510 1.8 christos if (!_bfd_generic_verify_endian_match (ibfd, info)) 511 1.1 christos return false; 512 1.1 christos 513 1.1 christos /* If they're not both mt, then merging is meaningless, so just 514 1.1 christos don't do it. */ 515 1.8 christos if (strcmp (ibfd->arch_info->arch_name, "mt") != 0) 516 1.1 christos return true; 517 1.8 christos if (strcmp (obfd->arch_info->arch_name, "mt") != 0) 518 1.1 christos return true; 519 1.1 christos 520 1.1 christos new_flags = elf_elfheader (ibfd)->e_flags; 521 1.1 christos old_flags = elf_elfheader (obfd)->e_flags; 522 1.1 christos 523 1.6 christos #ifdef DEBUG 524 1.1 christos _bfd_error_handler ("%pB: old_flags = 0x%.8x, new_flags = 0x%.8x, init = %s", 525 1.1 christos ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no"); 526 1.1 christos #endif 527 1.1 christos 528 1.1 christos if (!elf_flags_init (obfd)) 529 1.1 christos { 530 1.8 christos old_flags = new_flags; 531 1.1 christos elf_flags_init (obfd) = true; 532 1.1 christos } 533 1.1 christos else if ((new_flags & EF_MT_CPU_MASK) != (old_flags & EF_MT_CPU_MASK)) 534 1.1 christos { 535 1.1 christos /* CPU has changed. This is invalid, because MRISC, MRISC2 and 536 1.8 christos MS2 are not subsets of each other. */ 537 1.1 christos ok = false; 538 1.3 christos } 539 1.1 christos 540 1.1 christos if (ok) 541 1.1 christos { 542 1.1 christos obfd->arch_info = ibfd->arch_info; 543 1.1 christos elf_elfheader (obfd)->e_flags = old_flags; 544 1.1 christos } 545 1.1 christos 546 1.1 christos return ok; 547 1.1 christos } 548 1.8 christos 549 1.8 christos static bool 550 1.1 christos mt_elf_print_private_bfd_data (bfd *abfd, void *ptr) 551 1.8 christos { 552 1.1 christos FILE *file = (FILE *) ptr; 553 1.1 christos flagword flags; 554 1.1 christos 555 1.3 christos BFD_ASSERT (abfd != NULL && ptr != NULL); 556 1.1 christos 557 1.1 christos /* Print normal ELF private data. */ 558 1.1 christos _bfd_elf_print_private_bfd_data (abfd, ptr); 559 1.1 christos 560 1.1 christos flags = elf_elfheader (abfd)->e_flags; 561 1.1 christos fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags); 562 1.1 christos 563 1.1 christos switch (flags & EF_MT_CPU_MASK) 564 1.1 christos { 565 1.1 christos default: 566 1.1 christos case EF_MT_CPU_MRISC: fprintf (file, " ms1-16-002"); break; 567 1.1 christos case EF_MT_CPU_MRISC2: fprintf (file, " ms1-16-003"); break; 568 1.1 christos case EF_MT_CPU_MS2: fprintf (file, " ms2"); break; 569 1.1 christos } 570 1.1 christos 571 1.1 christos fputc ('\n', file); 572 1.8 christos 573 1.1 christos return true; 574 1.1 christos } 575 1.1 christos 576 1.3 christos 577 1.6 christos #define TARGET_BIG_SYM mt_elf32_vec 579 1.1 christos #define TARGET_BIG_NAME "elf32-mt" 580 1.1 christos 581 1.6 christos #define ELF_ARCH bfd_arch_mt 582 1.1 christos #define ELF_MACHINE_CODE EM_MT 583 1.1 christos #define ELF_MAXPAGESIZE 1 /* No pages on the MT. */ 584 1.1 christos 585 1.1 christos #define elf_info_to_howto_rel NULL 586 1.1 christos #define elf_info_to_howto mt_info_to_howto_rela 587 1.1 christos 588 1.6 christos #define elf_backend_relocate_section mt_elf_relocate_section 589 1.6 christos 590 1.1 christos #define bfd_elf32_bfd_reloc_type_lookup mt_reloc_type_lookup 591 1.6 christos #define bfd_elf32_bfd_reloc_name_lookup mt_reloc_name_lookup 592 1.6 christos 593 1.1 christos #define elf_backend_check_relocs mt_elf_check_relocs 594 1.1 christos #define elf_backend_object_p mt_elf_object_p 595 1.1 christos #define elf_backend_rela_normal 1 596 1.1 christos 597 1.1 christos #define elf_backend_can_gc_sections 1 598 1.1 christos 599 1.1 christos #define bfd_elf32_bfd_set_private_flags mt_elf_set_private_flags 600 1.1 christos #define bfd_elf32_bfd_merge_private_bfd_data mt_elf_merge_private_bfd_data 601 1.1 christos #define bfd_elf32_bfd_print_private_bfd_data mt_elf_print_private_bfd_data 602 603 #include "elf32-target.h" 604