1 1.1 skrll /* Motorola MCore specific support for 32-bit ELF 2 1.1.1.12 christos Copyright (C) 1994-2026 Free Software Foundation, Inc. 3 1.1 skrll 4 1.1 skrll This file is part of BFD, the Binary File Descriptor library. 5 1.1 skrll 6 1.1 skrll This program is free software; you can redistribute it and/or modify 7 1.1 skrll it under the terms of the GNU General Public License as published by 8 1.1 skrll the Free Software Foundation; either version 3 of the License, or 9 1.1 skrll (at your option) any later version. 10 1.1 skrll 11 1.1 skrll This program is distributed in the hope that it will be useful, 12 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 skrll GNU General Public License for more details. 15 1.1 skrll 16 1.1 skrll You should have received a copy of the GNU General Public License 17 1.1 skrll along with this program; if not, write to the Free Software 18 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 1.1 skrll MA 02110-1301, USA. */ 20 1.1 skrll 21 1.1 skrll 22 1.1 skrll /* This file is based on a preliminary RCE ELF ABI. The 23 1.1 skrll information may not match the final RCE ELF ABI. */ 24 1.1 skrll 25 1.1 skrll #include "sysdep.h" 26 1.1 skrll #include "bfd.h" 27 1.1 skrll #include "bfdlink.h" 28 1.1 skrll #include "libbfd.h" 29 1.1 skrll #include "elf-bfd.h" 30 1.1 skrll #include "elf/mcore.h" 31 1.1 skrll #include <assert.h> 32 1.1 skrll 33 1.1 skrll /* RELA relocs are used here... */ 34 1.1 skrll 35 1.1 skrll /* Function to set whether a module needs the -mrelocatable bit set. */ 36 1.1 skrll 37 1.1.1.9 christos static bool 38 1.1 skrll mcore_elf_set_private_flags (bfd * abfd, flagword flags) 39 1.1 skrll { 40 1.1 skrll BFD_ASSERT (! elf_flags_init (abfd) 41 1.1 skrll || elf_elfheader (abfd)->e_flags == flags); 42 1.1 skrll 43 1.1 skrll elf_elfheader (abfd)->e_flags = flags; 44 1.1.1.9 christos elf_flags_init (abfd) = true; 45 1.1.1.9 christos return true; 46 1.1 skrll } 47 1.1 skrll 48 1.1 skrll /* Merge backend specific data from an object file to the output 49 1.1 skrll object file when linking. */ 50 1.1 skrll 51 1.1.1.9 christos static bool 52 1.1.1.6 christos mcore_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 53 1.1 skrll { 54 1.1.1.6 christos bfd *obfd = info->output_bfd; 55 1.1 skrll flagword old_flags; 56 1.1 skrll flagword new_flags; 57 1.1 skrll 58 1.1.1.3 christos /* Check if we have the same endianness. */ 59 1.1.1.6 christos if (! _bfd_generic_verify_endian_match (ibfd, info)) 60 1.1.1.9 christos return false; 61 1.1 skrll 62 1.1.1.12 christos if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) 63 1.1.1.9 christos return true; 64 1.1 skrll 65 1.1 skrll new_flags = elf_elfheader (ibfd)->e_flags; 66 1.1 skrll old_flags = elf_elfheader (obfd)->e_flags; 67 1.1 skrll 68 1.1 skrll if (! elf_flags_init (obfd)) 69 1.1 skrll { 70 1.1.1.6 christos /* First call, no flags set. */ 71 1.1.1.9 christos elf_flags_init (obfd) = true; 72 1.1 skrll elf_elfheader (obfd)->e_flags = new_flags; 73 1.1 skrll } 74 1.1 skrll else if (new_flags == old_flags) 75 1.1 skrll /* Compatible flags are OK. */ 76 1.1 skrll ; 77 1.1 skrll else 78 1.1 skrll { 79 1.1 skrll /* FIXME */ 80 1.1 skrll } 81 1.1 skrll 82 1.1.1.9 christos return true; 83 1.1 skrll } 84 1.1 skrll 85 1.1 skrll /* Don't pretend we can deal with unsupported relocs. */ 87 1.1 skrll 88 1.1 skrll static bfd_reloc_status_type 89 1.1 skrll mcore_elf_unsupported_reloc (bfd * abfd, 90 1.1 skrll arelent * reloc_entry, 91 1.1.1.3 christos asymbol * symbol ATTRIBUTE_UNUSED, 92 1.1 skrll void * data ATTRIBUTE_UNUSED, 93 1.1 skrll asection * input_section ATTRIBUTE_UNUSED, 94 1.1 skrll bfd * output_bfd ATTRIBUTE_UNUSED, 95 1.1 skrll char ** error_message ATTRIBUTE_UNUSED) 96 1.1 skrll { 97 1.1 skrll BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0); 98 1.1.1.6 christos 99 1.1.1.7 christos /* xgettext:c-format */ 100 1.1 skrll _bfd_error_handler (_("%pB: %s unsupported"), 101 1.1.1.7 christos abfd, 102 1.1 skrll reloc_entry->howto->name); 103 1.1 skrll 104 1.1 skrll return bfd_reloc_notsupported; 105 1.1 skrll } 106 1.1 skrll 107 1.1 skrll static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max]; 108 1.1 skrll 109 1.1 skrll static reloc_howto_type mcore_elf_howto_raw[] = 110 1.1 skrll { 111 1.1 skrll /* This reloc does nothing. */ 112 1.1 skrll HOWTO (R_MCORE_NONE, /* type */ 113 1.1.1.9 christos 0, /* rightshift */ 114 1.1.1.4 christos 0, /* size */ 115 1.1.1.9 christos 0, /* bitsize */ 116 1.1 skrll false, /* pc_relative */ 117 1.1.1.4 christos 0, /* bitpos */ 118 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 119 1.1 skrll NULL, /* special_function */ 120 1.1.1.9 christos "R_MCORE_NONE", /* name */ 121 1.1 skrll false, /* partial_inplace */ 122 1.1 skrll 0, /* src_mask */ 123 1.1.1.9 christos 0, /* dst_mask */ 124 1.1 skrll false), /* pcrel_offset */ 125 1.1 skrll 126 1.1 skrll /* A standard 32 bit relocation. */ 127 1.1 skrll HOWTO (R_MCORE_ADDR32, /* type */ 128 1.1.1.9 christos 0, /* rightshift */ 129 1.1 skrll 4, /* size */ 130 1.1.1.9 christos 32, /* bitsize */ 131 1.1 skrll false, /* pc_relative */ 132 1.1 skrll 0, /* bitpos */ 133 1.1 skrll complain_overflow_bitfield, /* complain_on_overflow */ 134 1.1 skrll bfd_elf_generic_reloc, /* special_function */ 135 1.1.1.9 christos "ADDR32", /* name *//* For compatibility with coff/pe port. */ 136 1.1 skrll false, /* partial_inplace */ 137 1.1 skrll 0x0, /* src_mask */ 138 1.1.1.9 christos 0xffffffff, /* dst_mask */ 139 1.1 skrll false), /* pcrel_offset */ 140 1.1 skrll 141 1.1 skrll /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions. 142 1.1 skrll Should not appear in object files. */ 143 1.1 skrll HOWTO (R_MCORE_PCRELIMM8BY4, /* type */ 144 1.1.1.9 christos 2, /* rightshift */ 145 1.1 skrll 2, /* size */ 146 1.1.1.9 christos 8, /* bitsize */ 147 1.1 skrll true, /* pc_relative */ 148 1.1 skrll 0, /* bitpos */ 149 1.1 skrll complain_overflow_bitfield, /* complain_on_overflow */ 150 1.1 skrll mcore_elf_unsupported_reloc, /* special_function */ 151 1.1.1.9 christos "R_MCORE_PCRELIMM8BY4",/* name */ 152 1.1 skrll false, /* partial_inplace */ 153 1.1 skrll 0, /* src_mask */ 154 1.1.1.9 christos 0, /* dst_mask */ 155 1.1 skrll true), /* pcrel_offset */ 156 1.1 skrll 157 1.1 skrll /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit 158 1.1 skrll Span 2k instructions == 4k bytes. 159 1.1 skrll Only useful pieces at the relocated address are the opcode (5 bits) */ 160 1.1 skrll HOWTO (R_MCORE_PCRELIMM11BY2,/* type */ 161 1.1.1.9 christos 1, /* rightshift */ 162 1.1 skrll 2, /* size */ 163 1.1.1.9 christos 11, /* bitsize */ 164 1.1 skrll true, /* pc_relative */ 165 1.1 skrll 0, /* bitpos */ 166 1.1 skrll complain_overflow_signed, /* complain_on_overflow */ 167 1.1 skrll bfd_elf_generic_reloc, /* special_function */ 168 1.1.1.9 christos "R_MCORE_PCRELIMM11BY2",/* name */ 169 1.1 skrll false, /* partial_inplace */ 170 1.1 skrll 0x0, /* src_mask */ 171 1.1.1.9 christos 0x7ff, /* dst_mask */ 172 1.1 skrll true), /* pcrel_offset */ 173 1.1 skrll 174 1.1 skrll /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */ 175 1.1 skrll HOWTO (R_MCORE_PCRELIMM4BY2, /* type */ 176 1.1.1.9 christos 1, /* rightshift */ 177 1.1 skrll 2, /* size */ 178 1.1.1.9 christos 4, /* bitsize */ 179 1.1 skrll true, /* pc_relative */ 180 1.1 skrll 0, /* bitpos */ 181 1.1 skrll complain_overflow_bitfield, /* complain_on_overflow */ 182 1.1 skrll mcore_elf_unsupported_reloc,/* special_function */ 183 1.1.1.9 christos "R_MCORE_PCRELIMM4BY2",/* name */ 184 1.1 skrll false, /* partial_inplace */ 185 1.1 skrll 0, /* src_mask */ 186 1.1.1.9 christos 0, /* dst_mask */ 187 1.1 skrll true), /* pcrel_offset */ 188 1.1 skrll 189 1.1 skrll /* 32-bit pc-relative. Eventually this will help support PIC code. */ 190 1.1 skrll HOWTO (R_MCORE_PCREL32, /* type */ 191 1.1.1.9 christos 0, /* rightshift */ 192 1.1 skrll 4, /* size */ 193 1.1.1.9 christos 32, /* bitsize */ 194 1.1 skrll true, /* pc_relative */ 195 1.1 skrll 0, /* bitpos */ 196 1.1 skrll complain_overflow_bitfield, /* complain_on_overflow */ 197 1.1 skrll bfd_elf_generic_reloc, /* special_function */ 198 1.1.1.9 christos "R_MCORE_PCREL32", /* name */ 199 1.1 skrll false, /* partial_inplace */ 200 1.1 skrll 0x0, /* src_mask */ 201 1.1.1.9 christos 0xffffffff, /* dst_mask */ 202 1.1 skrll true), /* pcrel_offset */ 203 1.1 skrll 204 1.1 skrll /* Like PCRELIMM11BY2, this relocation indicates that there is a 205 1.1 skrll 'jsri' at the specified address. There is a separate relocation 206 1.1 skrll entry for the literal pool entry that it references, but we 207 1.1 skrll might be able to change the jsri to a bsr if the target turns out 208 1.1 skrll to be close enough [even though we won't reclaim the literal pool 209 1.1 skrll entry, we'll get some runtime efficiency back]. Note that this 210 1.1 skrll is a relocation that we are allowed to safely ignore. */ 211 1.1 skrll HOWTO (R_MCORE_PCRELJSR_IMM11BY2,/* type */ 212 1.1.1.9 christos 1, /* rightshift */ 213 1.1 skrll 2, /* size */ 214 1.1.1.9 christos 11, /* bitsize */ 215 1.1 skrll true, /* pc_relative */ 216 1.1 skrll 0, /* bitpos */ 217 1.1 skrll complain_overflow_signed, /* complain_on_overflow */ 218 1.1 skrll bfd_elf_generic_reloc, /* special_function */ 219 1.1.1.9 christos "R_MCORE_PCRELJSR_IMM11BY2", /* name */ 220 1.1 skrll false, /* partial_inplace */ 221 1.1 skrll 0x0, /* src_mask */ 222 1.1.1.9 christos 0x7ff, /* dst_mask */ 223 1.1 skrll true), /* pcrel_offset */ 224 1.1 skrll 225 1.1 skrll /* GNU extension to record C++ vtable hierarchy. */ 226 1.1.1.6 christos HOWTO (R_MCORE_GNU_VTINHERIT, /* type */ 227 1.1.1.9 christos 0, /* rightshift */ 228 1.1.1.6 christos 4, /* size */ 229 1.1.1.9 christos 0, /* bitsize */ 230 1.1.1.6 christos false, /* pc_relative */ 231 1.1.1.6 christos 0, /* bitpos */ 232 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 233 1.1.1.6 christos NULL, /* special_function */ 234 1.1.1.9 christos "R_MCORE_GNU_VTINHERIT", /* name */ 235 1.1.1.6 christos false, /* partial_inplace */ 236 1.1.1.6 christos 0, /* src_mask */ 237 1.1.1.9 christos 0, /* dst_mask */ 238 1.1 skrll false), /* pcrel_offset */ 239 1.1 skrll 240 1.1.1.6 christos /* GNU extension to record C++ vtable member usage. */ 241 1.1.1.6 christos HOWTO (R_MCORE_GNU_VTENTRY, /* type */ 242 1.1.1.9 christos 0, /* rightshift */ 243 1.1.1.6 christos 4, /* size */ 244 1.1.1.9 christos 0, /* bitsize */ 245 1.1.1.6 christos false, /* pc_relative */ 246 1.1.1.6 christos 0, /* bitpos */ 247 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 248 1.1.1.6 christos _bfd_elf_rel_vtable_reloc_fn, /* special_function */ 249 1.1.1.9 christos "R_MCORE_GNU_VTENTRY", /* name */ 250 1.1.1.6 christos false, /* partial_inplace */ 251 1.1.1.6 christos 0, /* src_mask */ 252 1.1.1.9 christos 0, /* dst_mask */ 253 1.1 skrll false), /* pcrel_offset */ 254 1.1.1.6 christos 255 1.1 skrll HOWTO (R_MCORE_RELATIVE, /* type */ 256 1.1.1.9 christos 0, /* rightshift */ 257 1.1 skrll 4, /* size */ 258 1.1.1.9 christos 32, /* bitsize */ 259 1.1 skrll false, /* pc_relative */ 260 1.1 skrll 0, /* bitpos */ 261 1.1.1.6 christos complain_overflow_signed, /* complain_on_overflow */ 262 1.1.1.6 christos NULL, /* special_function */ 263 1.1.1.9 christos "R_MCORE_RELATIVE", /* name */ 264 1.1 skrll true, /* partial_inplace */ 265 1.1 skrll 0xffffffff, /* src_mask */ 266 1.1.1.9 christos 0xffffffff, /* dst_mask */ 267 1.1 skrll false) /* pcrel_offset */ 268 1.1 skrll }; 269 1.1 skrll 270 1.1 skrll #ifndef NUM_ELEM 271 1.1 skrll #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) 272 1.1 skrll #endif 273 1.1 skrll 274 1.1 skrll /* Initialize the mcore_elf_howto_table, so that linear accesses can be done. */ 276 1.1 skrll static void 277 1.1 skrll mcore_elf_howto_init (void) 278 1.1 skrll { 279 1.1 skrll unsigned int i; 280 1.1 skrll 281 1.1 skrll for (i = NUM_ELEM (mcore_elf_howto_raw); i--;) 282 1.1 skrll { 283 1.1 skrll unsigned int type; 284 1.1 skrll 285 1.1 skrll type = mcore_elf_howto_raw[i].type; 286 1.1 skrll 287 1.1 skrll BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table)); 288 1.1 skrll 289 1.1 skrll mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i]; 290 1.1 skrll } 291 1.1 skrll } 292 1.1 skrll 293 1.1 skrll static reloc_howto_type * 295 1.1 skrll mcore_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, 296 1.1 skrll bfd_reloc_code_real_type code) 297 1.1 skrll { 298 1.1 skrll enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE; 299 1.1 skrll 300 1.1 skrll switch (code) 301 1.1 skrll { 302 1.1 skrll case BFD_RELOC_NONE: mcore_reloc = R_MCORE_NONE; break; 303 1.1 skrll case BFD_RELOC_32: mcore_reloc = R_MCORE_ADDR32; break; 304 1.1 skrll case BFD_RELOC_MCORE_PCREL_IMM8BY4: mcore_reloc = R_MCORE_PCRELIMM8BY4; break; 305 1.1 skrll case BFD_RELOC_MCORE_PCREL_IMM11BY2: mcore_reloc = R_MCORE_PCRELIMM11BY2; break; 306 1.1.1.6 christos case BFD_RELOC_MCORE_PCREL_IMM4BY2: mcore_reloc = R_MCORE_PCRELIMM4BY2; break; 307 1.1.1.6 christos case BFD_RELOC_32_PCREL: mcore_reloc = R_MCORE_PCREL32; break; 308 1.1.1.6 christos case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break; 309 1.1 skrll case BFD_RELOC_VTABLE_INHERIT: mcore_reloc = R_MCORE_GNU_VTINHERIT; break; 310 1.1 skrll case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break; 311 1.1 skrll case BFD_RELOC_RVA: mcore_reloc = R_MCORE_RELATIVE; break; 312 1.1 skrll default: 313 1.1 skrll return NULL; 314 1.1 skrll } 315 1.1 skrll 316 1.1 skrll if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) 317 1.1 skrll /* Initialize howto table if needed. */ 318 1.1 skrll mcore_elf_howto_init (); 319 1.1 skrll 320 1.1 skrll return mcore_elf_howto_table [(int) mcore_reloc]; 321 1.1 skrll }; 322 1.1 skrll 323 1.1 skrll static reloc_howto_type * 324 1.1 skrll mcore_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 325 1.1 skrll const char *r_name) 326 1.1 skrll { 327 1.1 skrll unsigned int i; 328 1.1 skrll 329 1.1 skrll for (i = 0; 330 1.1 skrll i < sizeof (mcore_elf_howto_raw) / sizeof (mcore_elf_howto_raw[0]); 331 1.1 skrll i++) 332 1.1 skrll if (mcore_elf_howto_raw[i].name != NULL 333 1.1 skrll && strcasecmp (mcore_elf_howto_raw[i].name, r_name) == 0) 334 1.1 skrll return &mcore_elf_howto_raw[i]; 335 1.1 skrll 336 1.1 skrll return NULL; 337 1.1 skrll } 338 1.1.1.9 christos 339 1.1.1.7 christos /* Set the howto pointer for a RCE ELF reloc. */ 340 1.1 skrll 341 1.1 skrll static bool 342 1.1 skrll mcore_elf_info_to_howto (bfd * abfd, 343 1.1.1.4 christos arelent * cache_ptr, 344 1.1.1.4 christos Elf_Internal_Rela * dst) 345 1.1 skrll { 346 1.1 skrll unsigned int r_type; 347 1.1 skrll 348 1.1 skrll if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) 349 1.1.1.4 christos /* Initialize howto table if needed. */ 350 1.1.1.4 christos mcore_elf_howto_init (); 351 1.1.1.4 christos 352 1.1.1.6 christos r_type = ELF32_R_TYPE (dst->r_info); 353 1.1.1.7 christos if (r_type >= R_MCORE_max) 354 1.1.1.6 christos { 355 1.1.1.4 christos /* xgettext:c-format */ 356 1.1.1.9 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 357 1.1.1.4 christos abfd, r_type); 358 1.1 skrll bfd_set_error (bfd_error_bad_value); 359 1.1.1.4 christos return false; 360 1.1.1.9 christos } 361 1.1 skrll 362 1.1 skrll cache_ptr->howto = mcore_elf_howto_table [r_type]; 363 1.1 skrll return true; 364 1.1 skrll } 365 1.1 skrll 366 1.1 skrll /* The RELOCATE_SECTION function is called by the ELF backend linker 368 1.1 skrll to handle the relocations for a section. 369 1.1 skrll 370 1.1 skrll The relocs are always passed as Rela structures; if the section 371 1.1 skrll actually uses Rel structures, the r_addend field will always be 372 1.1 skrll zero. 373 1.1 skrll 374 1.1 skrll This function is responsible for adjust the section contents as 375 1.1 skrll necessary, and (if using Rela relocs and generating a 376 1.1 skrll relocatable output file) adjusting the reloc addend as 377 1.1 skrll necessary. 378 1.1 skrll 379 1.1 skrll This function does not have to worry about setting the reloc 380 1.1 skrll address or the reloc symbol index. 381 1.1 skrll 382 1.1 skrll LOCAL_SYMS is a pointer to the swapped in local symbols. 383 1.1 skrll 384 1.1 skrll LOCAL_SECTIONS is an array giving the section in the input file 385 1.1 skrll corresponding to the st_shndx field of each local symbol. 386 1.1 skrll 387 1.1 skrll The global hash table entry for the global symbols can be found 388 1.1 skrll via elf_sym_hashes (input_bfd). 389 1.1 skrll 390 1.1 skrll When generating relocatable output, this function must handle 391 1.1 skrll STB_LOCAL/STT_SECTION symbols specially. The output symbol is 392 1.1.1.9 christos going to be the section symbol corresponding to the output 393 1.1 skrll section, which means that the addend must be adjusted 394 1.1 skrll accordingly. */ 395 1.1 skrll 396 1.1 skrll static int 397 1.1 skrll mcore_elf_relocate_section (bfd * output_bfd, 398 1.1 skrll struct bfd_link_info * info, 399 1.1 skrll bfd * input_bfd, 400 1.1 skrll asection * input_section, 401 1.1 skrll bfd_byte * contents, 402 1.1 skrll Elf_Internal_Rela * relocs, 403 1.1 skrll Elf_Internal_Sym * local_syms, 404 1.1 skrll asection ** local_sections) 405 1.1 skrll { 406 1.1.1.9 christos Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 407 1.1 skrll struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd); 408 1.1 skrll Elf_Internal_Rela * rel = relocs; 409 1.1 skrll Elf_Internal_Rela * relend = relocs + input_section->reloc_count; 410 1.1.1.7 christos bool ret = true; 411 1.1 skrll 412 1.1 skrll #ifdef DEBUG 413 1.1.1.6 christos _bfd_error_handler 414 1.1.1.4 christos ("mcore_elf_relocate_section called for %pB section %pA, %u relocations%s", 415 1.1 skrll input_bfd, 416 1.1 skrll input_section, 417 1.1 skrll input_section->reloc_count, 418 1.1 skrll (bfd_link_relocatable (info)) ? " (relocatable)" : ""); 419 1.1 skrll #endif 420 1.1 skrll 421 1.1 skrll if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */ 422 1.1.1.6 christos mcore_elf_howto_init (); 423 1.1.1.6 christos 424 1.1.1.6 christos for (; rel < relend; rel++) 425 1.1.1.6 christos { 426 1.1.1.6 christos enum elf_mcore_reloc_type r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info); 427 1.1.1.6 christos bfd_vma offset = rel->r_offset; 428 1.1.1.6 christos bfd_vma addend = rel->r_addend; 429 1.1.1.6 christos bfd_reloc_status_type r = bfd_reloc_other; 430 1.1.1.6 christos asection * sec = NULL; 431 1.1 skrll reloc_howto_type * howto; 432 1.1.1.6 christos bfd_vma relocation; 433 1.1 skrll Elf_Internal_Sym * sym = NULL; 434 1.1 skrll unsigned long r_symndx; 435 1.1 skrll struct elf_link_hash_entry * h = NULL; 436 1.1 skrll unsigned short oldinst = 0; 437 1.1 skrll 438 1.1.1.6 christos /* Unknown relocation handling. */ 439 1.1.1.7 christos if ((unsigned) r_type >= (unsigned) R_MCORE_max 440 1.1 skrll || ! mcore_elf_howto_table [(int)r_type]) 441 1.1 skrll { 442 1.1 skrll /* xgettext:c-format */ 443 1.1.1.9 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 444 1.1 skrll input_bfd, (int) r_type); 445 1.1 skrll 446 1.1 skrll bfd_set_error (bfd_error_bad_value); 447 1.1 skrll ret = false; 448 1.1 skrll continue; 449 1.1 skrll } 450 1.1 skrll 451 1.1 skrll howto = mcore_elf_howto_table [(int) r_type]; 452 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info); 453 1.1.1.6 christos 454 1.1.1.7 christos /* Complain about known relocation that are not yet supported. */ 455 1.1 skrll if (howto->special_function == mcore_elf_unsupported_reloc) 456 1.1.1.7 christos { 457 1.1 skrll /* xgettext:c-format */ 458 1.1 skrll _bfd_error_handler (_("%pB: %s unsupported"), 459 1.1.1.9 christos input_bfd, 460 1.1 skrll howto->name); 461 1.1 skrll 462 1.1 skrll bfd_set_error (bfd_error_bad_value); 463 1.1 skrll ret = false; 464 1.1 skrll continue; 465 1.1 skrll } 466 1.1 skrll 467 1.1 skrll if (r_symndx < symtab_hdr->sh_info) 468 1.1 skrll { 469 1.1 skrll sym = local_syms + r_symndx; 470 1.1 skrll sec = local_sections [r_symndx]; 471 1.1 skrll relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 472 1.1.1.9 christos addend = rel->r_addend; 473 1.1 skrll } 474 1.1 skrll else 475 1.1 skrll { 476 1.1 skrll bool unresolved_reloc, warned, ignored; 477 1.1.1.4 christos 478 1.1 skrll RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 479 1.1 skrll r_symndx, symtab_hdr, sym_hashes, 480 1.1.1.3 christos h, sec, relocation, 481 1.1.1.2 christos unresolved_reloc, warned, ignored); 482 1.1.1.12 christos } 483 1.1.1.12 christos 484 1.1 skrll if (sec != NULL && discarded_section (sec)) 485 1.1.1.4 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 486 1.1 skrll rel, 1, relend, R_MCORE_NONE, 487 1.1 skrll howto, 0, contents); 488 1.1 skrll 489 1.1 skrll if (bfd_link_relocatable (info)) 490 1.1 skrll continue; 491 1.1 skrll 492 1.1 skrll switch (r_type) 493 1.1 skrll { 494 1.1 skrll default: 495 1.1 skrll break; 496 1.1 skrll 497 1.1 skrll case R_MCORE_PCRELJSR_IMM11BY2: 498 1.1 skrll oldinst = bfd_get_16 (input_bfd, contents + offset); 499 1.1 skrll #define MCORE_INST_BSR 0xF800 500 1.1 skrll bfd_put_16 (input_bfd, (bfd_vma) MCORE_INST_BSR, contents + offset); 501 1.1 skrll break; 502 1.1 skrll } 503 1.1 skrll 504 1.1 skrll #ifdef DEBUG 505 1.1 skrll fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n", 506 1.1 skrll howto->name, r_type, r_symndx, (long) offset, (long) addend); 507 1.1 skrll #endif 508 1.1 skrll 509 1.1 skrll r = _bfd_final_link_relocate 510 1.1 skrll (howto, input_bfd, input_section, contents, offset, relocation, addend); 511 1.1 skrll 512 1.1 skrll if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2) 513 1.1 skrll { 514 1.1 skrll /* Wasn't ok, back it out and give up. */ 515 1.1 skrll bfd_put_16 (input_bfd, (bfd_vma) oldinst, contents + offset); 516 1.1 skrll r = bfd_reloc_ok; 517 1.1.1.9 christos } 518 1.1 skrll 519 1.1 skrll if (r != bfd_reloc_ok) 520 1.1 skrll { 521 1.1 skrll ret = false; 522 1.1 skrll 523 1.1 skrll switch (r) 524 1.1 skrll { 525 1.1 skrll default: 526 1.1 skrll break; 527 1.1 skrll 528 1.1 skrll case bfd_reloc_overflow: 529 1.1 skrll { 530 1.1 skrll const char * name; 531 1.1 skrll 532 1.1 skrll if (h != NULL) 533 1.1 skrll name = NULL; 534 1.1 skrll else 535 1.1 skrll { 536 1.1 skrll name = bfd_elf_string_from_elf_section 537 1.1 skrll (input_bfd, symtab_hdr->sh_link, sym->st_name); 538 1.1 skrll 539 1.1.1.8 christos if (name == NULL) 540 1.1 skrll break; 541 1.1 skrll 542 1.1 skrll if (* name == '\0') 543 1.1 skrll name = bfd_section_name (sec); 544 1.1 skrll } 545 1.1 skrll 546 1.1 skrll (*info->callbacks->reloc_overflow) 547 1.1 skrll (info, (h ? &h->root : NULL), name, howto->name, 548 1.1 skrll (bfd_vma) 0, input_bfd, input_section, offset); 549 1.1 skrll } 550 1.1 skrll break; 551 1.1 skrll } 552 1.1 skrll } 553 1.1 skrll } 554 1.1 skrll 555 1.1 skrll #ifdef DEBUG 556 1.1 skrll fprintf (stderr, "\n"); 557 1.1 skrll #endif 558 1.1 skrll 559 1.1 skrll return ret; 560 1.1 skrll } 561 1.1 skrll 562 1.1 skrll /* Return the section that should be marked against GC for a given 564 1.1.1.12 christos relocation. */ 565 1.1 skrll 566 1.1.1.12 christos static asection * 567 1.1 skrll mcore_elf_gc_mark_hook (asection *sec, 568 1.1 skrll struct bfd_link_info *info, 569 1.1.1.12 christos struct elf_reloc_cookie *cookie, 570 1.1 skrll struct elf_link_hash_entry *h, 571 1.1 skrll unsigned int symndx) 572 1.1 skrll { 573 1.1 skrll if (h != NULL) 574 1.1 skrll switch (ELF32_R_TYPE (cookie->rel->r_info)) 575 1.1 skrll { 576 1.1.1.12 christos case R_MCORE_GNU_VTINHERIT: 577 1.1 skrll case R_MCORE_GNU_VTENTRY: 578 1.1 skrll return NULL; 579 1.1 skrll } 580 1.1 skrll 581 1.1 skrll return _bfd_elf_gc_mark_hook (sec, info, cookie, h, symndx); 582 1.1 skrll } 583 1.1.1.9 christos 584 1.1 skrll /* Look through the relocs for a section during the first phase. 585 1.1 skrll Since we don't do .gots or .plts, we just need to consider the 586 1.1 skrll virtual table relocs for gc. */ 587 1.1 skrll 588 1.1 skrll static bool 589 1.1 skrll mcore_elf_check_relocs (bfd * abfd, 590 1.1 skrll struct bfd_link_info * info, 591 1.1 skrll asection * sec, 592 1.1 skrll const Elf_Internal_Rela * relocs) 593 1.1 skrll { 594 1.1.1.4 christos Elf_Internal_Shdr * symtab_hdr; 595 1.1.1.9 christos struct elf_link_hash_entry ** sym_hashes; 596 1.1 skrll const Elf_Internal_Rela * rel; 597 1.1 skrll const Elf_Internal_Rela * rel_end; 598 1.1 skrll 599 1.1 skrll if (bfd_link_relocatable (info)) 600 1.1 skrll return true; 601 1.1 skrll 602 1.1 skrll symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 603 1.1 skrll sym_hashes = elf_sym_hashes (abfd); 604 1.1 skrll 605 1.1 skrll rel_end = relocs + sec->reloc_count; 606 1.1 skrll 607 1.1 skrll for (rel = relocs; rel < rel_end; rel++) 608 1.1 skrll { 609 1.1 skrll struct elf_link_hash_entry * h; 610 1.1.1.6 christos unsigned long r_symndx; 611 1.1 skrll 612 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info); 613 1.1 skrll 614 1.1 skrll if (r_symndx < symtab_hdr->sh_info) 615 1.1 skrll h = NULL; 616 1.1 skrll else 617 1.1 skrll { 618 1.1 skrll h = sym_hashes [r_symndx - symtab_hdr->sh_info]; 619 1.1 skrll while (h->root.type == bfd_link_hash_indirect 620 1.1.1.6 christos || h->root.type == bfd_link_hash_warning) 621 1.1.1.6 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 622 1.1.1.6 christos } 623 1.1.1.6 christos 624 1.1.1.6 christos switch (ELF32_R_TYPE (rel->r_info)) 625 1.1.1.9 christos { 626 1.1.1.6 christos /* This relocation describes the C++ object vtable hierarchy. 627 1.1.1.6 christos Reconstruct it for later use during GC. */ 628 1.1.1.6 christos case R_MCORE_GNU_VTINHERIT: 629 1.1.1.6 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 630 1.1.1.6 christos return false; 631 1.1.1.8 christos break; 632 1.1.1.9 christos 633 1.1.1.6 christos /* This relocation describes which C++ vtable entries are actually 634 1.1.1.6 christos used. Record for later use during GC. */ 635 1.1 skrll case R_MCORE_GNU_VTENTRY: 636 1.1 skrll if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) 637 1.1.1.9 christos return false; 638 1.1 skrll break; 639 1.1 skrll } 640 1.1 skrll } 641 1.1 skrll 642 1.1 skrll return true; 643 1.1 skrll } 644 1.1.1.6 christos 645 1.1 skrll static const struct bfd_elf_special_section mcore_elf_special_sections[]= 646 1.1 skrll { 647 1.1.1.4 christos { STRING_COMMA_LEN (".ctors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 648 1.1 skrll { STRING_COMMA_LEN (".dtors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 649 1.1.1.6 christos { NULL, 0, 0, 0, 0 } 650 1.1.1.6 christos }; 651 1.1 skrll 652 1.1 skrll #define TARGET_BIG_SYM mcore_elf32_be_vec 653 1.1 skrll #define TARGET_BIG_NAME "elf32-mcore-big" 654 1.1 skrll #define TARGET_LITTLE_SYM mcore_elf32_le_vec 655 1.1 skrll #define TARGET_LITTLE_NAME "elf32-mcore-little" 656 1.1 skrll 657 1.1 skrll #define ELF_ARCH bfd_arch_mcore 658 1.1 skrll #define ELF_MACHINE_CODE EM_MCORE 659 1.1 skrll #define ELF_MAXPAGESIZE 0x1000 /* 4k, if we ever have 'em */ 660 1.1 skrll #define elf_info_to_howto mcore_elf_info_to_howto 661 1.1 skrll #define elf_info_to_howto_rel NULL 662 1.1 skrll 663 1.1 skrll #define bfd_elf32_bfd_merge_private_bfd_data mcore_elf_merge_private_bfd_data 664 1.1.1.6 christos #define bfd_elf32_bfd_set_private_flags mcore_elf_set_private_flags 665 1.1 skrll #define bfd_elf32_bfd_reloc_type_lookup mcore_elf_reloc_type_lookup 666 1.1 skrll #define bfd_elf32_bfd_reloc_name_lookup mcore_elf_reloc_name_lookup 667 1.1 skrll #define elf_backend_relocate_section mcore_elf_relocate_section 668 1.1 skrll #define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook 669 1.1 skrll #define elf_backend_check_relocs mcore_elf_check_relocs 670 1.1 skrll #define elf_backend_special_sections mcore_elf_special_sections 671 672 #define elf_backend_can_gc_sections 1 673 #define elf_backend_rela_normal 1 674 675 #include "elf32-target.h" 676