1 1.1 skrll /* D10V-specific support for 32-bit ELF 2 1.1.1.12 christos Copyright (C) 1996-2026 Free Software Foundation, Inc. 3 1.1 skrll Contributed by Martin Hunt (hunt (at) cygnus.com). 4 1.1 skrll 5 1.1 skrll This file is part of BFD, the Binary File Descriptor library. 6 1.1 skrll 7 1.1 skrll This program is free software; you can redistribute it and/or modify 8 1.1 skrll it under the terms of the GNU General Public License as published by 9 1.1 skrll the Free Software Foundation; either version 3 of the License, or 10 1.1 skrll (at your option) any later version. 11 1.1 skrll 12 1.1 skrll This program is distributed in the hope that it will be useful, 13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 skrll GNU General Public License for more details. 16 1.1 skrll 17 1.1 skrll You should have received a copy of the GNU General Public License 18 1.1 skrll along with this program; if not, write to the Free Software 19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 skrll MA 02110-1301, USA. */ 21 1.1 skrll 22 1.1 skrll #include "sysdep.h" 23 1.1 skrll #include "bfd.h" 24 1.1 skrll #include "libbfd.h" 25 1.1 skrll #include "elf-bfd.h" 26 1.1 skrll #include "elf/d10v.h" 27 1.1 skrll 28 1.1 skrll /* Use REL instead of RELA to save space. */ 29 1.1 skrll #define USE_REL 1 30 1.1 skrll 31 1.1 skrll static reloc_howto_type elf_d10v_howto_table[] = 32 1.1 skrll { 33 1.1 skrll /* This reloc does nothing. */ 34 1.1 skrll HOWTO (R_D10V_NONE, /* Type. */ 35 1.1 skrll 0, /* Rightshift. */ 36 1.1.1.9 christos 0, /* Size. */ 37 1.1.1.4 christos 0, /* Bitsize. */ 38 1.1.1.9 christos false, /* PC_relative. */ 39 1.1 skrll 0, /* Bitpos. */ 40 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */ 41 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */ 42 1.1 skrll "R_D10V_NONE", /* Name. */ 43 1.1.1.9 christos false, /* Partial_inplace. */ 44 1.1 skrll 0, /* Src_mask. */ 45 1.1 skrll 0, /* Dst_mask. */ 46 1.1.1.9 christos false), /* PCrel_offset. */ 47 1.1 skrll 48 1.1 skrll /* An PC Relative 10-bit relocation, shifted by 2, right container. */ 49 1.1 skrll HOWTO (R_D10V_10_PCREL_R, /* Type. */ 50 1.1.1.6 christos 2, /* Rightshift. */ 51 1.1.1.9 christos 4, /* Size. */ 52 1.1.1.6 christos 8, /* Bitsize. */ 53 1.1.1.9 christos true, /* PC_relative. */ 54 1.1.1.6 christos 0, /* Bitpos. */ 55 1.1 skrll complain_overflow_signed, /* Complain_on_overflow. */ 56 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */ 57 1.1 skrll "R_D10V_10_PCREL_R", /* Name. */ 58 1.1.1.9 christos false, /* Partial_inplace. */ 59 1.1 skrll 0xff, /* Src_mask. */ 60 1.1.1.6 christos 0xff, /* Dst_mask. */ 61 1.1.1.9 christos true), /* PCrel_offset. */ 62 1.1 skrll 63 1.1 skrll /* An PC Relative 10-bit relocation, shifted by 2, left container. */ 64 1.1 skrll HOWTO (R_D10V_10_PCREL_L, /* Type. */ 65 1.1.1.6 christos 2, /* Rightshift. */ 66 1.1.1.9 christos 4, /* Size. */ 67 1.1.1.6 christos 8, /* Bitsize. */ 68 1.1.1.9 christos true, /* PC_relative. */ 69 1.1.1.6 christos 15, /* Bitpos. */ 70 1.1 skrll complain_overflow_signed, /* Complain_on_overflow. */ 71 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */ 72 1.1 skrll "R_D10V_10_PCREL_L", /* Name. */ 73 1.1.1.9 christos false, /* Partial_inplace. */ 74 1.1 skrll 0x07f8000, /* Src_mask. */ 75 1.1.1.6 christos 0x07f8000, /* Dst_mask. */ 76 1.1.1.9 christos true), /* PCrel_offset. */ 77 1.1 skrll 78 1.1 skrll /* A 16 bit absolute relocation. */ 79 1.1 skrll HOWTO (R_D10V_16, /* Type. */ 80 1.1 skrll 0, /* Rightshift. */ 81 1.1.1.9 christos 2, /* Size. */ 82 1.1 skrll 16, /* Bitsize. */ 83 1.1.1.9 christos false, /* PC_relative. */ 84 1.1 skrll 0, /* Bitpos. */ 85 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */ 86 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */ 87 1.1 skrll "R_D10V_16", /* Name. */ 88 1.1.1.9 christos false, /* Partial_inplace. */ 89 1.1 skrll 0xffff, /* Src_mask. */ 90 1.1 skrll 0xffff, /* Dst_mask. */ 91 1.1.1.9 christos false), /* PCrel_offset. */ 92 1.1 skrll 93 1.1 skrll /* An 18 bit absolute relocation, right shifted 2. */ 94 1.1 skrll HOWTO (R_D10V_18, /* Type. */ 95 1.1 skrll 2, /* Rightshift. */ 96 1.1.1.9 christos 2, /* Size. */ 97 1.1 skrll 16, /* Bitsize. */ 98 1.1.1.9 christos false, /* PC_relative. */ 99 1.1 skrll 0, /* Bitpos. */ 100 1.1 skrll complain_overflow_dont, /* Complain_on_overflow. */ 101 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */ 102 1.1 skrll "R_D10V_18", /* Name. */ 103 1.1.1.9 christos false, /* Partial_inplace. */ 104 1.1 skrll 0xffff, /* Src_mask. */ 105 1.1 skrll 0xffff, /* Dst_mask. */ 106 1.1.1.9 christos false), /* PCrel_offset. */ 107 1.1 skrll 108 1.1 skrll /* A relative 18 bit relocation, right shifted by 2. */ 109 1.1 skrll HOWTO (R_D10V_18_PCREL, /* Type. */ 110 1.1 skrll 2, /* Rightshift. */ 111 1.1.1.9 christos 4, /* Size. */ 112 1.1 skrll 16, /* Bitsize. */ 113 1.1.1.9 christos true, /* PC_relative. */ 114 1.1 skrll 0, /* Bitpos. */ 115 1.1 skrll complain_overflow_signed, /* Complain_on_overflow. */ 116 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */ 117 1.1 skrll "R_D10V_18_PCREL", /* Name. */ 118 1.1.1.9 christos false, /* Partial_inplace. */ 119 1.1 skrll 0xffff, /* Src_mask. */ 120 1.1 skrll 0xffff, /* Dst_mask. */ 121 1.1.1.9 christos true), /* PCrel_offset. */ 122 1.1 skrll 123 1.1 skrll /* A 32 bit absolute relocation. */ 124 1.1 skrll HOWTO (R_D10V_32, /* Type. */ 125 1.1 skrll 0, /* Rightshift. */ 126 1.1.1.9 christos 4, /* Size. */ 127 1.1 skrll 32, /* Bitsize. */ 128 1.1.1.9 christos false, /* PC_relative. */ 129 1.1 skrll 0, /* Bitpos. */ 130 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */ 131 1.1 skrll bfd_elf_generic_reloc, /* Special_function. */ 132 1.1 skrll "R_D10V_32", /* Name. */ 133 1.1.1.9 christos false, /* Partial_inplace. */ 134 1.1 skrll 0xffffffff, /* Src_mask. */ 135 1.1 skrll 0xffffffff, /* Dst_mask. */ 136 1.1.1.9 christos false), /* PCrel_offset. */ 137 1.1 skrll 138 1.1 skrll /* GNU extension to record C++ vtable hierarchy. */ 139 1.1 skrll HOWTO (R_D10V_GNU_VTINHERIT, /* Type. */ 140 1.1.1.6 christos 0, /* Rightshift. */ 141 1.1.1.9 christos 4, /* Size. */ 142 1.1.1.6 christos 0, /* Bitsize. */ 143 1.1.1.9 christos false, /* PC_relative. */ 144 1.1.1.6 christos 0, /* Bitpos. */ 145 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */ 146 1.1.1.6 christos NULL, /* Special_function. */ 147 1.1 skrll "R_D10V_GNU_VTINHERIT",/* Name. */ 148 1.1.1.9 christos false, /* Partial_inplace. */ 149 1.1.1.6 christos 0, /* Src_mask. */ 150 1.1.1.6 christos 0, /* Dst_mask. */ 151 1.1.1.9 christos false), /* PCrel_offset. */ 152 1.1 skrll 153 1.1 skrll /* GNU extension to record C++ vtable member usage. */ 154 1.1.1.6 christos HOWTO (R_D10V_GNU_VTENTRY, /* Type. */ 155 1.1.1.6 christos 0, /* Rightshift. */ 156 1.1.1.9 christos 4, /* Size. */ 157 1.1.1.6 christos 0, /* Bitsize. */ 158 1.1.1.9 christos false, /* PC_relative. */ 159 1.1.1.6 christos 0, /* Bitpos. */ 160 1.1 skrll complain_overflow_dont,/* Complain_on_overflow. */ 161 1.1 skrll _bfd_elf_rel_vtable_reloc_fn, /* Special_function. */ 162 1.1.1.6 christos "R_D10V_GNU_VTENTRY", /* Name. */ 163 1.1.1.9 christos false, /* Partial_inplace. */ 164 1.1.1.6 christos 0, /* Src_mask. */ 165 1.1.1.6 christos 0, /* Dst_mask. */ 166 1.1.1.9 christos false), /* PCrel_offset. */ 167 1.1 skrll }; 168 1.1 skrll 169 1.1 skrll /* Map BFD reloc types to D10V ELF reloc types. */ 170 1.1 skrll 171 1.1 skrll struct d10v_reloc_map 172 1.1 skrll { 173 1.1 skrll bfd_reloc_code_real_type bfd_reloc_val; 174 1.1 skrll unsigned char elf_reloc_val; 175 1.1 skrll }; 176 1.1 skrll 177 1.1 skrll static const struct d10v_reloc_map d10v_reloc_map[] = 178 1.1 skrll { 179 1.1 skrll { BFD_RELOC_NONE, R_D10V_NONE, }, 180 1.1 skrll { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R }, 181 1.1 skrll { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L }, 182 1.1 skrll { BFD_RELOC_16, R_D10V_16 }, 183 1.1 skrll { BFD_RELOC_D10V_18, R_D10V_18 }, 184 1.1 skrll { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL }, 185 1.1 skrll { BFD_RELOC_32, R_D10V_32 }, 186 1.1 skrll { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT }, 187 1.1 skrll { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY }, 188 1.1 skrll }; 189 1.1 skrll 190 1.1 skrll static reloc_howto_type * 191 1.1 skrll bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 192 1.1 skrll bfd_reloc_code_real_type code) 193 1.1 skrll { 194 1.1 skrll unsigned int i; 195 1.1 skrll 196 1.1 skrll for (i = 0; 197 1.1 skrll i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map); 198 1.1 skrll i++) 199 1.1 skrll if (d10v_reloc_map[i].bfd_reloc_val == code) 200 1.1 skrll return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val]; 201 1.1 skrll 202 1.1 skrll return NULL; 203 1.1 skrll } 204 1.1 skrll 205 1.1 skrll static reloc_howto_type * 206 1.1 skrll bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 207 1.1 skrll const char *r_name) 208 1.1 skrll { 209 1.1 skrll unsigned int i; 210 1.1 skrll 211 1.1 skrll for (i = 0; 212 1.1 skrll i < sizeof (elf_d10v_howto_table) / sizeof (elf_d10v_howto_table[0]); 213 1.1 skrll i++) 214 1.1 skrll if (elf_d10v_howto_table[i].name != NULL 215 1.1 skrll && strcasecmp (elf_d10v_howto_table[i].name, r_name) == 0) 216 1.1 skrll return &elf_d10v_howto_table[i]; 217 1.1 skrll 218 1.1 skrll return NULL; 219 1.1 skrll } 220 1.1 skrll 221 1.1 skrll /* Set the howto pointer for an D10V ELF reloc. */ 222 1.1 skrll 223 1.1.1.9 christos static bool 224 1.1.1.7 christos d10v_info_to_howto_rel (bfd *abfd, 225 1.1 skrll arelent *cache_ptr, 226 1.1 skrll Elf_Internal_Rela *dst) 227 1.1 skrll { 228 1.1 skrll unsigned int r_type; 229 1.1 skrll 230 1.1 skrll r_type = ELF32_R_TYPE (dst->r_info); 231 1.1.1.4 christos if (r_type >= (unsigned int) R_D10V_max) 232 1.1.1.4 christos { 233 1.1.1.6 christos /* xgettext:c-format */ 234 1.1.1.7 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 235 1.1.1.7 christos abfd, r_type); 236 1.1.1.7 christos bfd_set_error (bfd_error_bad_value); 237 1.1.1.9 christos return false; 238 1.1.1.4 christos } 239 1.1 skrll cache_ptr->howto = &elf_d10v_howto_table[r_type]; 240 1.1.1.9 christos return true; 241 1.1 skrll } 242 1.1 skrll 243 1.1 skrll static asection * 244 1.1 skrll elf32_d10v_gc_mark_hook (asection *sec, 245 1.1 skrll struct bfd_link_info *info, 246 1.1.1.12 christos struct elf_reloc_cookie *cookie, 247 1.1 skrll struct elf_link_hash_entry *h, 248 1.1.1.12 christos unsigned int symndx) 249 1.1 skrll { 250 1.1 skrll if (h != NULL) 251 1.1.1.12 christos switch (ELF32_R_TYPE (cookie->rel->r_info)) 252 1.1 skrll { 253 1.1 skrll case R_D10V_GNU_VTINHERIT: 254 1.1 skrll case R_D10V_GNU_VTENTRY: 255 1.1 skrll return NULL; 256 1.1 skrll } 257 1.1 skrll 258 1.1.1.12 christos return _bfd_elf_gc_mark_hook (sec, info, cookie, h, symndx); 259 1.1 skrll } 260 1.1 skrll 261 1.1 skrll /* Look through the relocs for a section during the first phase. 262 1.1 skrll Since we don't do .gots or .plts, we just need to consider the 263 1.1 skrll virtual table relocs for gc. */ 264 1.1 skrll 265 1.1.1.9 christos static bool 266 1.1 skrll elf32_d10v_check_relocs (bfd *abfd, 267 1.1 skrll struct bfd_link_info *info, 268 1.1 skrll asection *sec, 269 1.1 skrll const Elf_Internal_Rela *relocs) 270 1.1 skrll { 271 1.1 skrll Elf_Internal_Shdr *symtab_hdr; 272 1.1 skrll struct elf_link_hash_entry **sym_hashes; 273 1.1 skrll const Elf_Internal_Rela *rel; 274 1.1 skrll const Elf_Internal_Rela *rel_end; 275 1.1 skrll 276 1.1.1.4 christos if (bfd_link_relocatable (info)) 277 1.1.1.9 christos return true; 278 1.1 skrll 279 1.1 skrll symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 280 1.1 skrll sym_hashes = elf_sym_hashes (abfd); 281 1.1 skrll 282 1.1 skrll rel_end = relocs + sec->reloc_count; 283 1.1 skrll for (rel = relocs; rel < rel_end; rel++) 284 1.1 skrll { 285 1.1 skrll struct elf_link_hash_entry *h; 286 1.1 skrll unsigned long r_symndx; 287 1.1 skrll 288 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info); 289 1.1 skrll if (r_symndx < symtab_hdr->sh_info) 290 1.1.1.6 christos h = NULL; 291 1.1 skrll else 292 1.1 skrll { 293 1.1 skrll h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 294 1.1 skrll while (h->root.type == bfd_link_hash_indirect 295 1.1 skrll || h->root.type == bfd_link_hash_warning) 296 1.1 skrll h = (struct elf_link_hash_entry *) h->root.u.i.link; 297 1.1 skrll } 298 1.1 skrll 299 1.1 skrll switch (ELF32_R_TYPE (rel->r_info)) 300 1.1.1.6 christos { 301 1.1.1.6 christos /* This relocation describes the C++ object vtable hierarchy. 302 1.1.1.6 christos Reconstruct it for later use during GC. */ 303 1.1.1.6 christos case R_D10V_GNU_VTINHERIT: 304 1.1.1.6 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 305 1.1.1.9 christos return false; 306 1.1.1.6 christos break; 307 1.1.1.6 christos 308 1.1.1.6 christos /* This relocation describes which C++ vtable entries are actually 309 1.1.1.6 christos used. Record for later use during GC. */ 310 1.1.1.6 christos case R_D10V_GNU_VTENTRY: 311 1.1.1.8 christos if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) 312 1.1.1.9 christos return false; 313 1.1.1.6 christos break; 314 1.1.1.6 christos } 315 1.1 skrll } 316 1.1 skrll 317 1.1.1.9 christos return true; 318 1.1 skrll } 319 1.1 skrll 320 1.1 skrll static bfd_vma 321 1.1 skrll extract_rel_addend (bfd *abfd, 322 1.1 skrll bfd_byte *where, 323 1.1 skrll reloc_howto_type *howto) 324 1.1 skrll { 325 1.1 skrll bfd_vma insn, val; 326 1.1 skrll 327 1.1.1.9 christos switch (bfd_get_reloc_size (howto)) 328 1.1 skrll { 329 1.1.1.9 christos case 1: 330 1.1 skrll insn = bfd_get_8 (abfd, where); 331 1.1 skrll break; 332 1.1.1.9 christos case 2: 333 1.1 skrll insn = bfd_get_16 (abfd, where); 334 1.1 skrll break; 335 1.1.1.9 christos case 4: 336 1.1 skrll insn = bfd_get_32 (abfd, where); 337 1.1 skrll break; 338 1.1 skrll default: 339 1.1 skrll abort (); 340 1.1 skrll } 341 1.1 skrll 342 1.1 skrll val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift; 343 1.1 skrll /* We should really be testing for signed addends here, but we don't 344 1.1 skrll have that info directly in the howto. */ 345 1.1 skrll if (howto->pc_relative) 346 1.1 skrll { 347 1.1 skrll bfd_vma sign; 348 1.1 skrll sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1)); 349 1.1 skrll sign = sign >> howto->bitpos << howto->rightshift; 350 1.1 skrll val = (val ^ sign) - sign; 351 1.1 skrll } 352 1.1 skrll return val; 353 1.1 skrll } 354 1.1 skrll 355 1.1 skrll static void 356 1.1 skrll insert_rel_addend (bfd *abfd, 357 1.1 skrll bfd_byte *where, 358 1.1 skrll reloc_howto_type *howto, 359 1.1 skrll bfd_vma addend) 360 1.1 skrll { 361 1.1 skrll bfd_vma insn; 362 1.1 skrll 363 1.1 skrll addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask; 364 1.1 skrll insn = ~howto->dst_mask; 365 1.1.1.9 christos switch (bfd_get_reloc_size (howto)) 366 1.1 skrll { 367 1.1.1.9 christos case 1: 368 1.1 skrll insn &= bfd_get_8 (abfd, where); 369 1.1 skrll insn |= addend; 370 1.1 skrll bfd_put_8 (abfd, insn, where); 371 1.1 skrll break; 372 1.1.1.9 christos case 2: 373 1.1 skrll insn &= bfd_get_16 (abfd, where); 374 1.1 skrll insn |= addend; 375 1.1 skrll bfd_put_16 (abfd, insn, where); 376 1.1 skrll break; 377 1.1.1.9 christos case 4: 378 1.1 skrll insn &= bfd_get_32 (abfd, where); 379 1.1 skrll insn |= addend; 380 1.1 skrll bfd_put_32 (abfd, insn, where); 381 1.1 skrll break; 382 1.1 skrll default: 383 1.1 skrll abort (); 384 1.1 skrll } 385 1.1 skrll } 386 1.1 skrll 387 1.1 skrll /* Relocate a D10V ELF section. */ 388 1.1 skrll 389 1.1.1.9 christos static int 390 1.1 skrll elf32_d10v_relocate_section (bfd *output_bfd, 391 1.1 skrll struct bfd_link_info *info, 392 1.1 skrll bfd *input_bfd, 393 1.1 skrll asection *input_section, 394 1.1 skrll bfd_byte *contents, 395 1.1 skrll Elf_Internal_Rela *relocs, 396 1.1 skrll Elf_Internal_Sym *local_syms, 397 1.1 skrll asection **local_sections) 398 1.1 skrll { 399 1.1 skrll Elf_Internal_Shdr *symtab_hdr; 400 1.1 skrll struct elf_link_hash_entry **sym_hashes; 401 1.1 skrll Elf_Internal_Rela *rel, *relend; 402 1.1 skrll const char *name; 403 1.1 skrll 404 1.1 skrll symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 405 1.1 skrll sym_hashes = elf_sym_hashes (input_bfd); 406 1.1 skrll 407 1.1 skrll rel = relocs; 408 1.1 skrll relend = relocs + input_section->reloc_count; 409 1.1 skrll for (; rel < relend; rel++) 410 1.1 skrll { 411 1.1 skrll int r_type; 412 1.1 skrll reloc_howto_type *howto; 413 1.1 skrll unsigned long r_symndx; 414 1.1 skrll Elf_Internal_Sym *sym; 415 1.1 skrll asection *sec; 416 1.1 skrll struct elf_link_hash_entry *h; 417 1.1 skrll bfd_vma relocation; 418 1.1 skrll bfd_reloc_status_type r; 419 1.1 skrll 420 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info); 421 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info); 422 1.1 skrll 423 1.1 skrll if (r_type == R_D10V_GNU_VTENTRY 424 1.1.1.6 christos || r_type == R_D10V_GNU_VTINHERIT) 425 1.1.1.6 christos continue; 426 1.1 skrll 427 1.1 skrll howto = elf_d10v_howto_table + r_type; 428 1.1 skrll h = NULL; 429 1.1 skrll sym = NULL; 430 1.1 skrll sec = NULL; 431 1.1 skrll if (r_symndx < symtab_hdr->sh_info) 432 1.1 skrll { 433 1.1 skrll sym = local_syms + r_symndx; 434 1.1 skrll sec = local_sections[r_symndx]; 435 1.1 skrll relocation = (sec->output_section->vma 436 1.1 skrll + sec->output_offset 437 1.1 skrll + sym->st_value); 438 1.1 skrll if (ELF_ST_TYPE (sym->st_info) == STT_SECTION 439 1.1 skrll && ((sec->flags & SEC_MERGE) != 0 440 1.1.1.4 christos || (bfd_link_relocatable (info) 441 1.1 skrll && sec->output_offset != 0))) 442 1.1 skrll { 443 1.1 skrll bfd_vma addend; 444 1.1 skrll bfd_byte *where = contents + rel->r_offset; 445 1.1 skrll 446 1.1 skrll addend = extract_rel_addend (input_bfd, where, howto); 447 1.1 skrll 448 1.1.1.4 christos if (bfd_link_relocatable (info)) 449 1.1 skrll addend += sec->output_offset; 450 1.1 skrll else 451 1.1 skrll { 452 1.1 skrll asection *msec = sec; 453 1.1 skrll addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, 454 1.1 skrll addend); 455 1.1 skrll addend -= relocation; 456 1.1 skrll addend += msec->output_section->vma + msec->output_offset; 457 1.1 skrll } 458 1.1 skrll insert_rel_addend (input_bfd, where, howto, addend); 459 1.1 skrll } 460 1.1 skrll } 461 1.1 skrll else 462 1.1 skrll { 463 1.1.1.9 christos bool unresolved_reloc, warned, ignored; 464 1.1 skrll 465 1.1 skrll RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 466 1.1 skrll r_symndx, symtab_hdr, sym_hashes, 467 1.1 skrll h, sec, relocation, 468 1.1.1.4 christos unresolved_reloc, warned, ignored); 469 1.1 skrll } 470 1.1 skrll 471 1.1.1.3 christos if (sec != NULL && discarded_section (sec)) 472 1.1.1.2 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 473 1.1.1.12 christos rel, 1, relend, R_D10V_NONE, 474 1.1.1.12 christos howto, 0, contents); 475 1.1 skrll 476 1.1.1.4 christos if (bfd_link_relocatable (info)) 477 1.1 skrll continue; 478 1.1 skrll 479 1.1 skrll if (h != NULL) 480 1.1 skrll name = h->root.root.string; 481 1.1 skrll else 482 1.1 skrll { 483 1.1 skrll name = (bfd_elf_string_from_elf_section 484 1.1 skrll (input_bfd, symtab_hdr->sh_link, sym->st_name)); 485 1.1 skrll if (name == NULL || *name == '\0') 486 1.1.1.8 christos name = bfd_section_name (sec); 487 1.1 skrll } 488 1.1 skrll 489 1.1 skrll r = _bfd_final_link_relocate (howto, input_bfd, input_section, 490 1.1.1.6 christos contents, rel->r_offset, 491 1.1.1.6 christos relocation, (bfd_vma) 0); 492 1.1 skrll 493 1.1 skrll if (r != bfd_reloc_ok) 494 1.1 skrll { 495 1.1 skrll const char * msg = (const char *) 0; 496 1.1 skrll 497 1.1 skrll switch (r) 498 1.1 skrll { 499 1.1 skrll case bfd_reloc_overflow: 500 1.1.1.5 christos (*info->callbacks->reloc_overflow) 501 1.1.1.5 christos (info, (h ? &h->root : NULL), name, howto->name, 502 1.1.1.5 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 503 1.1 skrll break; 504 1.1 skrll 505 1.1 skrll case bfd_reloc_undefined: 506 1.1.1.5 christos (*info->callbacks->undefined_symbol) 507 1.1.1.9 christos (info, name, input_bfd, input_section, rel->r_offset, true); 508 1.1 skrll break; 509 1.1 skrll 510 1.1 skrll case bfd_reloc_outofrange: 511 1.1 skrll msg = _("internal error: out of range error"); 512 1.1 skrll goto common_error; 513 1.1 skrll 514 1.1 skrll case bfd_reloc_notsupported: 515 1.1 skrll msg = _("internal error: unsupported relocation error"); 516 1.1 skrll goto common_error; 517 1.1 skrll 518 1.1 skrll case bfd_reloc_dangerous: 519 1.1 skrll msg = _("internal error: dangerous error"); 520 1.1 skrll goto common_error; 521 1.1 skrll 522 1.1 skrll default: 523 1.1 skrll msg = _("internal error: unknown error"); 524 1.1 skrll /* fall through */ 525 1.1 skrll 526 1.1 skrll common_error: 527 1.1.1.5 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 528 1.1.1.5 christos input_section, rel->r_offset); 529 1.1 skrll break; 530 1.1 skrll } 531 1.1 skrll } 532 1.1 skrll } 533 1.1 skrll 534 1.1.1.9 christos return true; 535 1.1 skrll } 536 1.1 skrll #define ELF_ARCH bfd_arch_d10v 537 1.1 skrll #define ELF_MACHINE_CODE EM_D10V 538 1.1 skrll #define ELF_MACHINE_ALT1 EM_CYGNUS_D10V 539 1.1 skrll #define ELF_MAXPAGESIZE 0x1000 540 1.1 skrll 541 1.1.1.6 christos #define TARGET_BIG_SYM d10v_elf32_vec 542 1.1 skrll #define TARGET_BIG_NAME "elf32-d10v" 543 1.1 skrll 544 1.1.1.7 christos #define elf_info_to_howto NULL 545 1.1.1.6 christos #define elf_info_to_howto_rel d10v_info_to_howto_rel 546 1.1.1.6 christos #define elf_backend_object_p 0 547 1.1.1.6 christos #define elf_backend_gc_mark_hook elf32_d10v_gc_mark_hook 548 1.1.1.6 christos #define elf_backend_check_relocs elf32_d10v_check_relocs 549 1.1.1.6 christos #define elf_backend_relocate_section elf32_d10v_relocate_section 550 1.1.1.6 christos #define elf_backend_can_gc_sections 1 551 1.1 skrll 552 1.1 skrll #include "elf32-target.h" 553