1 /* MIPS-specific support for 64-bit ELF 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 3 2006, 2007, 2008, 2009, 2010 4 Free Software Foundation, Inc. 5 Ian Lance Taylor, Cygnus Support 6 Linker support added by Mark Mitchell, CodeSourcery, LLC. 7 <mark@codesourcery.com> 8 9 This file is part of BFD, the Binary File Descriptor library. 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 24 MA 02110-1301, USA. */ 25 26 27 /* This file supports the 64-bit MIPS ELF ABI. 28 29 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file 30 overrides the usual ELF reloc handling, and handles reading and 31 writing the relocations here. */ 32 33 /* TODO: Many things are unsupported, even if there is some code for it 34 . (which was mostly stolen from elf32-mips.c and slightly adapted). 35 . 36 . - Relocation handling for REL relocs is wrong in many cases and 37 . generally untested. 38 . - Relocation handling for RELA relocs related to GOT support are 39 . also likely to be wrong. 40 . - Support for MIPS16 is untested. 41 . - Combined relocs with RSS_* entries are unsupported. 42 . - The whole GOT handling for NewABI is missing, some parts of 43 . the OldABI version is still lying around and should be removed. 44 */ 45 46 #include "sysdep.h" 47 #include "bfd.h" 48 #include "libbfd.h" 49 #include "aout/ar.h" 50 #include "bfdlink.h" 51 #include "genlink.h" 52 #include "elf-bfd.h" 53 #include "elfxx-mips.h" 54 #include "elf/mips.h" 55 56 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to 57 use ECOFF. However, we support it anyhow for an easier changeover. */ 58 #include "coff/sym.h" 59 #include "coff/symconst.h" 60 #include "coff/internal.h" 61 #include "coff/ecoff.h" 62 /* The 64 bit versions of the mdebug data structures are in alpha.h. */ 63 #include "coff/alpha.h" 64 #define ECOFF_SIGNED_64 65 #include "ecoffswap.h" 66 67 static void mips_elf64_swap_reloc_in 68 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *); 69 static void mips_elf64_swap_reloca_in 70 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *); 71 static void mips_elf64_swap_reloc_out 72 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *); 73 static void mips_elf64_swap_reloca_out 74 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *); 75 static void mips_elf64_be_swap_reloc_in 76 (bfd *, const bfd_byte *, Elf_Internal_Rela *); 77 static void mips_elf64_be_swap_reloc_out 78 (bfd *, const Elf_Internal_Rela *, bfd_byte *); 79 static void mips_elf64_be_swap_reloca_in 80 (bfd *, const bfd_byte *, Elf_Internal_Rela *); 81 static void mips_elf64_be_swap_reloca_out 82 (bfd *, const Elf_Internal_Rela *, bfd_byte *); 83 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup 84 (bfd *, bfd_reloc_code_real_type); 85 static reloc_howto_type *mips_elf64_rtype_to_howto 86 (unsigned int, bfd_boolean); 87 static void mips_elf64_info_to_howto_rel 88 (bfd *, arelent *, Elf_Internal_Rela *); 89 static void mips_elf64_info_to_howto_rela 90 (bfd *, arelent *, Elf_Internal_Rela *); 91 static long mips_elf64_get_reloc_upper_bound 92 (bfd *, asection *); 93 static long mips_elf64_canonicalize_reloc 94 (bfd *, asection *, arelent **, asymbol **); 95 static long mips_elf64_get_dynamic_reloc_upper_bound 96 (bfd *); 97 static long mips_elf64_canonicalize_dynamic_reloc 98 (bfd *, arelent **, asymbol **); 99 static bfd_boolean mips_elf64_slurp_one_reloc_table 100 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *, 101 asymbol **, bfd_boolean); 102 static bfd_boolean mips_elf64_slurp_reloc_table 103 (bfd *, asection *, asymbol **, bfd_boolean); 104 static void mips_elf64_write_relocs 105 (bfd *, asection *, void *); 106 static void mips_elf64_write_rel 107 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *); 108 static void mips_elf64_write_rela 109 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *); 110 static bfd_reloc_status_type mips_elf64_gprel16_reloc 111 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 112 static bfd_reloc_status_type mips_elf64_literal_reloc 113 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 114 static bfd_reloc_status_type mips_elf64_gprel32_reloc 115 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 116 static bfd_reloc_status_type mips_elf64_shift6_reloc 117 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 118 static bfd_reloc_status_type mips16_gprel_reloc 119 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 120 static bfd_boolean mips_elf64_assign_gp 121 (bfd *, bfd_vma *); 122 static bfd_reloc_status_type mips_elf64_final_gp 123 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *); 124 static bfd_boolean mips_elf64_object_p 125 (bfd *); 126 static irix_compat_t elf64_mips_irix_compat 127 (bfd *); 128 static bfd_boolean elf64_mips_grok_prstatus 129 (bfd *, Elf_Internal_Note *); 130 static bfd_boolean elf64_mips_grok_psinfo 131 (bfd *, Elf_Internal_Note *); 132 133 extern const bfd_target bfd_elf64_bigmips_vec; 134 extern const bfd_target bfd_elf64_littlemips_vec; 135 136 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value 137 from smaller values. Start with zero, widen, *then* decrement. */ 138 #define MINUS_ONE (((bfd_vma)0) - 1) 139 140 /* The number of local .got entries we reserve. */ 141 #define MIPS_RESERVED_GOTNO (2) 142 143 /* The relocation table used for SHT_REL sections. */ 144 145 static reloc_howto_type mips_elf64_howto_table_rel[] = 146 { 147 /* No relocation. */ 148 HOWTO (R_MIPS_NONE, /* type */ 149 0, /* rightshift */ 150 0, /* size (0 = byte, 1 = short, 2 = long) */ 151 0, /* bitsize */ 152 FALSE, /* pc_relative */ 153 0, /* bitpos */ 154 complain_overflow_dont, /* complain_on_overflow */ 155 _bfd_mips_elf_generic_reloc, /* special_function */ 156 "R_MIPS_NONE", /* name */ 157 FALSE, /* partial_inplace */ 158 0, /* src_mask */ 159 0, /* dst_mask */ 160 FALSE), /* pcrel_offset */ 161 162 /* 16 bit relocation. */ 163 HOWTO (R_MIPS_16, /* type */ 164 0, /* rightshift */ 165 2, /* size (0 = byte, 1 = short, 2 = long) */ 166 16, /* bitsize */ 167 FALSE, /* pc_relative */ 168 0, /* bitpos */ 169 complain_overflow_signed, /* complain_on_overflow */ 170 _bfd_mips_elf_generic_reloc, /* special_function */ 171 "R_MIPS_16", /* name */ 172 TRUE, /* partial_inplace */ 173 0x0000ffff, /* src_mask */ 174 0x0000ffff, /* dst_mask */ 175 FALSE), /* pcrel_offset */ 176 177 /* 32 bit relocation. */ 178 HOWTO (R_MIPS_32, /* type */ 179 0, /* rightshift */ 180 2, /* size (0 = byte, 1 = short, 2 = long) */ 181 32, /* bitsize */ 182 FALSE, /* pc_relative */ 183 0, /* bitpos */ 184 complain_overflow_dont, /* complain_on_overflow */ 185 _bfd_mips_elf_generic_reloc, /* special_function */ 186 "R_MIPS_32", /* name */ 187 TRUE, /* partial_inplace */ 188 0xffffffff, /* src_mask */ 189 0xffffffff, /* dst_mask */ 190 FALSE), /* pcrel_offset */ 191 192 /* 32 bit symbol relative relocation. */ 193 HOWTO (R_MIPS_REL32, /* type */ 194 0, /* rightshift */ 195 2, /* size (0 = byte, 1 = short, 2 = long) */ 196 32, /* bitsize */ 197 FALSE, /* pc_relative */ 198 0, /* bitpos */ 199 complain_overflow_dont, /* complain_on_overflow */ 200 _bfd_mips_elf_generic_reloc, /* special_function */ 201 "R_MIPS_REL32", /* name */ 202 TRUE, /* partial_inplace */ 203 0xffffffff, /* src_mask */ 204 0xffffffff, /* dst_mask */ 205 FALSE), /* pcrel_offset */ 206 207 /* 26 bit jump address. */ 208 HOWTO (R_MIPS_26, /* type */ 209 2, /* rightshift */ 210 2, /* size (0 = byte, 1 = short, 2 = long) */ 211 26, /* bitsize */ 212 FALSE, /* pc_relative */ 213 0, /* bitpos */ 214 complain_overflow_dont, /* complain_on_overflow */ 215 /* This needs complex overflow 216 detection, because the upper 36 217 bits must match the PC + 4. */ 218 _bfd_mips_elf_generic_reloc, /* special_function */ 219 "R_MIPS_26", /* name */ 220 TRUE, /* partial_inplace */ 221 0x03ffffff, /* src_mask */ 222 0x03ffffff, /* dst_mask */ 223 FALSE), /* pcrel_offset */ 224 225 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL. 226 However, the native IRIX6 tools use them, so we try our best. */ 227 228 /* High 16 bits of symbol value. */ 229 HOWTO (R_MIPS_HI16, /* type */ 230 16, /* rightshift */ 231 2, /* size (0 = byte, 1 = short, 2 = long) */ 232 16, /* bitsize */ 233 FALSE, /* pc_relative */ 234 0, /* bitpos */ 235 complain_overflow_dont, /* complain_on_overflow */ 236 _bfd_mips_elf_hi16_reloc, /* special_function */ 237 "R_MIPS_HI16", /* name */ 238 TRUE, /* partial_inplace */ 239 0x0000ffff, /* src_mask */ 240 0x0000ffff, /* dst_mask */ 241 FALSE), /* pcrel_offset */ 242 243 /* Low 16 bits of symbol value. */ 244 HOWTO (R_MIPS_LO16, /* type */ 245 0, /* rightshift */ 246 2, /* size (0 = byte, 1 = short, 2 = long) */ 247 16, /* bitsize */ 248 FALSE, /* pc_relative */ 249 0, /* bitpos */ 250 complain_overflow_dont, /* complain_on_overflow */ 251 _bfd_mips_elf_lo16_reloc, /* special_function */ 252 "R_MIPS_LO16", /* name */ 253 TRUE, /* partial_inplace */ 254 0x0000ffff, /* src_mask */ 255 0x0000ffff, /* dst_mask */ 256 FALSE), /* pcrel_offset */ 257 258 /* GP relative reference. */ 259 HOWTO (R_MIPS_GPREL16, /* type */ 260 0, /* rightshift */ 261 2, /* size (0 = byte, 1 = short, 2 = long) */ 262 16, /* bitsize */ 263 FALSE, /* pc_relative */ 264 0, /* bitpos */ 265 complain_overflow_signed, /* complain_on_overflow */ 266 mips_elf64_gprel16_reloc, /* special_function */ 267 "R_MIPS_GPREL16", /* name */ 268 TRUE, /* partial_inplace */ 269 0x0000ffff, /* src_mask */ 270 0x0000ffff, /* dst_mask */ 271 FALSE), /* pcrel_offset */ 272 273 /* Reference to literal section. */ 274 HOWTO (R_MIPS_LITERAL, /* type */ 275 0, /* rightshift */ 276 2, /* size (0 = byte, 1 = short, 2 = long) */ 277 16, /* bitsize */ 278 FALSE, /* pc_relative */ 279 0, /* bitpos */ 280 complain_overflow_signed, /* complain_on_overflow */ 281 mips_elf64_literal_reloc, /* special_function */ 282 "R_MIPS_LITERAL", /* name */ 283 TRUE, /* partial_inplace */ 284 0x0000ffff, /* src_mask */ 285 0x0000ffff, /* dst_mask */ 286 FALSE), /* pcrel_offset */ 287 288 /* Reference to global offset table. */ 289 HOWTO (R_MIPS_GOT16, /* type */ 290 0, /* rightshift */ 291 2, /* size (0 = byte, 1 = short, 2 = long) */ 292 16, /* bitsize */ 293 FALSE, /* pc_relative */ 294 0, /* bitpos */ 295 complain_overflow_signed, /* complain_on_overflow */ 296 _bfd_mips_elf_got16_reloc, /* special_function */ 297 "R_MIPS_GOT16", /* name */ 298 TRUE, /* partial_inplace */ 299 0x0000ffff, /* src_mask */ 300 0x0000ffff, /* dst_mask */ 301 FALSE), /* pcrel_offset */ 302 303 /* 16 bit PC relative reference. Note that the ABI document has a typo 304 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless. 305 We do the right thing here. */ 306 HOWTO (R_MIPS_PC16, /* type */ 307 2, /* rightshift */ 308 2, /* size (0 = byte, 1 = short, 2 = long) */ 309 16, /* bitsize */ 310 TRUE, /* pc_relative */ 311 0, /* bitpos */ 312 complain_overflow_signed, /* complain_on_overflow */ 313 _bfd_mips_elf_generic_reloc, /* special_function */ 314 "R_MIPS_PC16", /* name */ 315 TRUE, /* partial_inplace */ 316 0x0000ffff, /* src_mask */ 317 0x0000ffff, /* dst_mask */ 318 TRUE), /* pcrel_offset */ 319 320 /* 16 bit call through global offset table. */ 321 HOWTO (R_MIPS_CALL16, /* type */ 322 0, /* rightshift */ 323 2, /* size (0 = byte, 1 = short, 2 = long) */ 324 16, /* bitsize */ 325 FALSE, /* pc_relative */ 326 0, /* bitpos */ 327 complain_overflow_signed, /* complain_on_overflow */ 328 _bfd_mips_elf_generic_reloc, /* special_function */ 329 "R_MIPS_CALL16", /* name */ 330 TRUE, /* partial_inplace */ 331 0x0000ffff, /* src_mask */ 332 0x0000ffff, /* dst_mask */ 333 FALSE), /* pcrel_offset */ 334 335 /* 32 bit GP relative reference. */ 336 HOWTO (R_MIPS_GPREL32, /* type */ 337 0, /* rightshift */ 338 2, /* size (0 = byte, 1 = short, 2 = long) */ 339 32, /* bitsize */ 340 FALSE, /* pc_relative */ 341 0, /* bitpos */ 342 complain_overflow_dont, /* complain_on_overflow */ 343 mips_elf64_gprel32_reloc, /* special_function */ 344 "R_MIPS_GPREL32", /* name */ 345 TRUE, /* partial_inplace */ 346 0xffffffff, /* src_mask */ 347 0xffffffff, /* dst_mask */ 348 FALSE), /* pcrel_offset */ 349 350 EMPTY_HOWTO (13), 351 EMPTY_HOWTO (14), 352 EMPTY_HOWTO (15), 353 354 /* A 5 bit shift field. */ 355 HOWTO (R_MIPS_SHIFT5, /* type */ 356 0, /* rightshift */ 357 2, /* size (0 = byte, 1 = short, 2 = long) */ 358 5, /* bitsize */ 359 FALSE, /* pc_relative */ 360 6, /* bitpos */ 361 complain_overflow_bitfield, /* complain_on_overflow */ 362 _bfd_mips_elf_generic_reloc, /* special_function */ 363 "R_MIPS_SHIFT5", /* name */ 364 TRUE, /* partial_inplace */ 365 0x000007c0, /* src_mask */ 366 0x000007c0, /* dst_mask */ 367 FALSE), /* pcrel_offset */ 368 369 /* A 6 bit shift field. */ 370 HOWTO (R_MIPS_SHIFT6, /* type */ 371 0, /* rightshift */ 372 2, /* size (0 = byte, 1 = short, 2 = long) */ 373 6, /* bitsize */ 374 FALSE, /* pc_relative */ 375 6, /* bitpos */ 376 complain_overflow_bitfield, /* complain_on_overflow */ 377 mips_elf64_shift6_reloc, /* special_function */ 378 "R_MIPS_SHIFT6", /* name */ 379 TRUE, /* partial_inplace */ 380 0x000007c4, /* src_mask */ 381 0x000007c4, /* dst_mask */ 382 FALSE), /* pcrel_offset */ 383 384 /* 64 bit relocation. */ 385 HOWTO (R_MIPS_64, /* type */ 386 0, /* rightshift */ 387 4, /* size (0 = byte, 1 = short, 2 = long) */ 388 64, /* bitsize */ 389 FALSE, /* pc_relative */ 390 0, /* bitpos */ 391 complain_overflow_dont, /* complain_on_overflow */ 392 _bfd_mips_elf_generic_reloc, /* special_function */ 393 "R_MIPS_64", /* name */ 394 TRUE, /* partial_inplace */ 395 MINUS_ONE, /* src_mask */ 396 MINUS_ONE, /* dst_mask */ 397 FALSE), /* pcrel_offset */ 398 399 /* Displacement in the global offset table. */ 400 HOWTO (R_MIPS_GOT_DISP, /* type */ 401 0, /* rightshift */ 402 2, /* size (0 = byte, 1 = short, 2 = long) */ 403 16, /* bitsize */ 404 FALSE, /* pc_relative */ 405 0, /* bitpos */ 406 complain_overflow_signed, /* complain_on_overflow */ 407 _bfd_mips_elf_generic_reloc, /* special_function */ 408 "R_MIPS_GOT_DISP", /* name */ 409 TRUE, /* partial_inplace */ 410 0x0000ffff, /* src_mask */ 411 0x0000ffff, /* dst_mask */ 412 FALSE), /* pcrel_offset */ 413 414 /* Displacement to page pointer in the global offset table. */ 415 HOWTO (R_MIPS_GOT_PAGE, /* type */ 416 0, /* rightshift */ 417 2, /* size (0 = byte, 1 = short, 2 = long) */ 418 16, /* bitsize */ 419 FALSE, /* pc_relative */ 420 0, /* bitpos */ 421 complain_overflow_signed, /* complain_on_overflow */ 422 _bfd_mips_elf_generic_reloc, /* special_function */ 423 "R_MIPS_GOT_PAGE", /* name */ 424 TRUE, /* partial_inplace */ 425 0x0000ffff, /* src_mask */ 426 0x0000ffff, /* dst_mask */ 427 FALSE), /* pcrel_offset */ 428 429 /* Offset from page pointer in the global offset table. */ 430 HOWTO (R_MIPS_GOT_OFST, /* type */ 431 0, /* rightshift */ 432 2, /* size (0 = byte, 1 = short, 2 = long) */ 433 16, /* bitsize */ 434 FALSE, /* pc_relative */ 435 0, /* bitpos */ 436 complain_overflow_signed, /* complain_on_overflow */ 437 _bfd_mips_elf_generic_reloc, /* special_function */ 438 "R_MIPS_GOT_OFST", /* name */ 439 TRUE, /* partial_inplace */ 440 0x0000ffff, /* src_mask */ 441 0x0000ffff, /* dst_mask */ 442 FALSE), /* pcrel_offset */ 443 444 /* High 16 bits of displacement in global offset table. */ 445 HOWTO (R_MIPS_GOT_HI16, /* type */ 446 0, /* rightshift */ 447 2, /* size (0 = byte, 1 = short, 2 = long) */ 448 16, /* bitsize */ 449 FALSE, /* pc_relative */ 450 0, /* bitpos */ 451 complain_overflow_dont, /* complain_on_overflow */ 452 _bfd_mips_elf_generic_reloc, /* special_function */ 453 "R_MIPS_GOT_HI16", /* name */ 454 TRUE, /* partial_inplace */ 455 0x0000ffff, /* src_mask */ 456 0x0000ffff, /* dst_mask */ 457 FALSE), /* pcrel_offset */ 458 459 /* Low 16 bits of displacement in global offset table. */ 460 HOWTO (R_MIPS_GOT_LO16, /* type */ 461 0, /* rightshift */ 462 2, /* size (0 = byte, 1 = short, 2 = long) */ 463 16, /* bitsize */ 464 FALSE, /* pc_relative */ 465 0, /* bitpos */ 466 complain_overflow_dont, /* complain_on_overflow */ 467 _bfd_mips_elf_generic_reloc, /* special_function */ 468 "R_MIPS_GOT_LO16", /* name */ 469 TRUE, /* partial_inplace */ 470 0x0000ffff, /* src_mask */ 471 0x0000ffff, /* dst_mask */ 472 FALSE), /* pcrel_offset */ 473 474 /* 64 bit subtraction. */ 475 HOWTO (R_MIPS_SUB, /* type */ 476 0, /* rightshift */ 477 4, /* size (0 = byte, 1 = short, 2 = long) */ 478 64, /* bitsize */ 479 FALSE, /* pc_relative */ 480 0, /* bitpos */ 481 complain_overflow_dont, /* complain_on_overflow */ 482 _bfd_mips_elf_generic_reloc, /* special_function */ 483 "R_MIPS_SUB", /* name */ 484 TRUE, /* partial_inplace */ 485 MINUS_ONE, /* src_mask */ 486 MINUS_ONE, /* dst_mask */ 487 FALSE), /* pcrel_offset */ 488 489 /* Insert the addend as an instruction. */ 490 /* FIXME: Not handled correctly. */ 491 HOWTO (R_MIPS_INSERT_A, /* type */ 492 0, /* rightshift */ 493 2, /* size (0 = byte, 1 = short, 2 = long) */ 494 32, /* bitsize */ 495 FALSE, /* pc_relative */ 496 0, /* bitpos */ 497 complain_overflow_dont, /* complain_on_overflow */ 498 _bfd_mips_elf_generic_reloc, /* special_function */ 499 "R_MIPS_INSERT_A", /* name */ 500 TRUE, /* partial_inplace */ 501 0xffffffff, /* src_mask */ 502 0xffffffff, /* dst_mask */ 503 FALSE), /* pcrel_offset */ 504 505 /* Insert the addend as an instruction, and change all relocations 506 to refer to the old instruction at the address. */ 507 /* FIXME: Not handled correctly. */ 508 HOWTO (R_MIPS_INSERT_B, /* type */ 509 0, /* rightshift */ 510 2, /* size (0 = byte, 1 = short, 2 = long) */ 511 32, /* bitsize */ 512 FALSE, /* pc_relative */ 513 0, /* bitpos */ 514 complain_overflow_dont, /* complain_on_overflow */ 515 _bfd_mips_elf_generic_reloc, /* special_function */ 516 "R_MIPS_INSERT_B", /* name */ 517 TRUE, /* partial_inplace */ 518 0xffffffff, /* src_mask */ 519 0xffffffff, /* dst_mask */ 520 FALSE), /* pcrel_offset */ 521 522 /* Delete a 32 bit instruction. */ 523 /* FIXME: Not handled correctly. */ 524 HOWTO (R_MIPS_DELETE, /* type */ 525 0, /* rightshift */ 526 2, /* size (0 = byte, 1 = short, 2 = long) */ 527 32, /* bitsize */ 528 FALSE, /* pc_relative */ 529 0, /* bitpos */ 530 complain_overflow_dont, /* complain_on_overflow */ 531 _bfd_mips_elf_generic_reloc, /* special_function */ 532 "R_MIPS_DELETE", /* name */ 533 TRUE, /* partial_inplace */ 534 0xffffffff, /* src_mask */ 535 0xffffffff, /* dst_mask */ 536 FALSE), /* pcrel_offset */ 537 538 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations. 539 We don't, because 540 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/ 541 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using 542 fallable heuristics. 543 b) No other NewABI toolchain actually emits such relocations. */ 544 EMPTY_HOWTO (R_MIPS_HIGHER), 545 EMPTY_HOWTO (R_MIPS_HIGHEST), 546 547 /* High 16 bits of displacement in global offset table. */ 548 HOWTO (R_MIPS_CALL_HI16, /* type */ 549 0, /* rightshift */ 550 2, /* size (0 = byte, 1 = short, 2 = long) */ 551 16, /* bitsize */ 552 FALSE, /* pc_relative */ 553 0, /* bitpos */ 554 complain_overflow_dont, /* complain_on_overflow */ 555 _bfd_mips_elf_generic_reloc, /* special_function */ 556 "R_MIPS_CALL_HI16", /* name */ 557 TRUE, /* partial_inplace */ 558 0x0000ffff, /* src_mask */ 559 0x0000ffff, /* dst_mask */ 560 FALSE), /* pcrel_offset */ 561 562 /* Low 16 bits of displacement in global offset table. */ 563 HOWTO (R_MIPS_CALL_LO16, /* type */ 564 0, /* rightshift */ 565 2, /* size (0 = byte, 1 = short, 2 = long) */ 566 16, /* bitsize */ 567 FALSE, /* pc_relative */ 568 0, /* bitpos */ 569 complain_overflow_dont, /* complain_on_overflow */ 570 _bfd_mips_elf_generic_reloc, /* special_function */ 571 "R_MIPS_CALL_LO16", /* name */ 572 TRUE, /* partial_inplace */ 573 0x0000ffff, /* src_mask */ 574 0x0000ffff, /* dst_mask */ 575 FALSE), /* pcrel_offset */ 576 577 /* Section displacement, used by an associated event location section. */ 578 HOWTO (R_MIPS_SCN_DISP, /* type */ 579 0, /* rightshift */ 580 2, /* size (0 = byte, 1 = short, 2 = long) */ 581 32, /* bitsize */ 582 FALSE, /* pc_relative */ 583 0, /* bitpos */ 584 complain_overflow_dont, /* complain_on_overflow */ 585 _bfd_mips_elf_generic_reloc, /* special_function */ 586 "R_MIPS_SCN_DISP", /* name */ 587 TRUE, /* partial_inplace */ 588 0xffffffff, /* src_mask */ 589 0xffffffff, /* dst_mask */ 590 FALSE), /* pcrel_offset */ 591 592 HOWTO (R_MIPS_REL16, /* type */ 593 0, /* rightshift */ 594 1, /* size (0 = byte, 1 = short, 2 = long) */ 595 16, /* bitsize */ 596 FALSE, /* pc_relative */ 597 0, /* bitpos */ 598 complain_overflow_signed, /* complain_on_overflow */ 599 _bfd_mips_elf_generic_reloc, /* special_function */ 600 "R_MIPS_REL16", /* name */ 601 TRUE, /* partial_inplace */ 602 0xffff, /* src_mask */ 603 0xffff, /* dst_mask */ 604 FALSE), /* pcrel_offset */ 605 606 /* These two are obsolete. */ 607 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE), 608 EMPTY_HOWTO (R_MIPS_PJUMP), 609 610 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section. 611 It must be used for multigot GOT's (and only there). */ 612 HOWTO (R_MIPS_RELGOT, /* type */ 613 0, /* rightshift */ 614 2, /* size (0 = byte, 1 = short, 2 = long) */ 615 32, /* bitsize */ 616 FALSE, /* pc_relative */ 617 0, /* bitpos */ 618 complain_overflow_dont, /* complain_on_overflow */ 619 _bfd_mips_elf_generic_reloc, /* special_function */ 620 "R_MIPS_RELGOT", /* name */ 621 TRUE, /* partial_inplace */ 622 0xffffffff, /* src_mask */ 623 0xffffffff, /* dst_mask */ 624 FALSE), /* pcrel_offset */ 625 626 /* Protected jump conversion. This is an optimization hint. No 627 relocation is required for correctness. */ 628 HOWTO (R_MIPS_JALR, /* type */ 629 0, /* rightshift */ 630 2, /* size (0 = byte, 1 = short, 2 = long) */ 631 32, /* bitsize */ 632 FALSE, /* pc_relative */ 633 0, /* bitpos */ 634 complain_overflow_dont, /* complain_on_overflow */ 635 _bfd_mips_elf_generic_reloc, /* special_function */ 636 "R_MIPS_JALR", /* name */ 637 FALSE, /* partial_inplace */ 638 0, /* src_mask */ 639 0x00000000, /* dst_mask */ 640 FALSE), /* pcrel_offset */ 641 642 /* TLS relocations. */ 643 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32), 644 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32), 645 646 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */ 647 0, /* rightshift */ 648 4, /* size (0 = byte, 1 = short, 2 = long) */ 649 64, /* bitsize */ 650 FALSE, /* pc_relative */ 651 0, /* bitpos */ 652 complain_overflow_dont, /* complain_on_overflow */ 653 _bfd_mips_elf_generic_reloc, /* special_function */ 654 "R_MIPS_TLS_DTPMOD64", /* name */ 655 TRUE, /* partial_inplace */ 656 MINUS_ONE, /* src_mask */ 657 MINUS_ONE, /* dst_mask */ 658 FALSE), /* pcrel_offset */ 659 660 HOWTO (R_MIPS_TLS_DTPREL64, /* type */ 661 0, /* rightshift */ 662 4, /* size (0 = byte, 1 = short, 2 = long) */ 663 64, /* bitsize */ 664 FALSE, /* pc_relative */ 665 0, /* bitpos */ 666 complain_overflow_dont, /* complain_on_overflow */ 667 _bfd_mips_elf_generic_reloc, /* special_function */ 668 "R_MIPS_TLS_DTPREL64", /* name */ 669 TRUE, /* partial_inplace */ 670 MINUS_ONE, /* src_mask */ 671 MINUS_ONE, /* dst_mask */ 672 FALSE), /* pcrel_offset */ 673 674 /* TLS general dynamic variable reference. */ 675 HOWTO (R_MIPS_TLS_GD, /* type */ 676 0, /* rightshift */ 677 2, /* size (0 = byte, 1 = short, 2 = long) */ 678 16, /* bitsize */ 679 FALSE, /* pc_relative */ 680 0, /* bitpos */ 681 complain_overflow_signed, /* complain_on_overflow */ 682 _bfd_mips_elf_generic_reloc, /* special_function */ 683 "R_MIPS_TLS_GD", /* name */ 684 TRUE, /* partial_inplace */ 685 0x0000ffff, /* src_mask */ 686 0x0000ffff, /* dst_mask */ 687 FALSE), /* pcrel_offset */ 688 689 /* TLS local dynamic variable reference. */ 690 HOWTO (R_MIPS_TLS_LDM, /* type */ 691 0, /* rightshift */ 692 2, /* size (0 = byte, 1 = short, 2 = long) */ 693 16, /* bitsize */ 694 FALSE, /* pc_relative */ 695 0, /* bitpos */ 696 complain_overflow_signed, /* complain_on_overflow */ 697 _bfd_mips_elf_generic_reloc, /* special_function */ 698 "R_MIPS_TLS_LDM", /* name */ 699 TRUE, /* partial_inplace */ 700 0x0000ffff, /* src_mask */ 701 0x0000ffff, /* dst_mask */ 702 FALSE), /* pcrel_offset */ 703 704 /* TLS local dynamic offset. */ 705 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */ 706 0, /* rightshift */ 707 2, /* size (0 = byte, 1 = short, 2 = long) */ 708 16, /* bitsize */ 709 FALSE, /* pc_relative */ 710 0, /* bitpos */ 711 complain_overflow_signed, /* complain_on_overflow */ 712 _bfd_mips_elf_generic_reloc, /* special_function */ 713 "R_MIPS_TLS_DTPREL_HI16", /* name */ 714 TRUE, /* partial_inplace */ 715 0x0000ffff, /* src_mask */ 716 0x0000ffff, /* dst_mask */ 717 FALSE), /* pcrel_offset */ 718 719 /* TLS local dynamic offset. */ 720 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */ 721 0, /* rightshift */ 722 2, /* size (0 = byte, 1 = short, 2 = long) */ 723 16, /* bitsize */ 724 FALSE, /* pc_relative */ 725 0, /* bitpos */ 726 complain_overflow_signed, /* complain_on_overflow */ 727 _bfd_mips_elf_generic_reloc, /* special_function */ 728 "R_MIPS_TLS_DTPREL_LO16", /* name */ 729 TRUE, /* partial_inplace */ 730 0x0000ffff, /* src_mask */ 731 0x0000ffff, /* dst_mask */ 732 FALSE), /* pcrel_offset */ 733 734 /* TLS thread pointer offset. */ 735 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */ 736 0, /* rightshift */ 737 2, /* size (0 = byte, 1 = short, 2 = long) */ 738 16, /* bitsize */ 739 FALSE, /* pc_relative */ 740 0, /* bitpos */ 741 complain_overflow_signed, /* complain_on_overflow */ 742 _bfd_mips_elf_generic_reloc, /* special_function */ 743 "R_MIPS_TLS_GOTTPREL", /* name */ 744 TRUE, /* partial_inplace */ 745 0x0000ffff, /* src_mask */ 746 0x0000ffff, /* dst_mask */ 747 FALSE), /* pcrel_offset */ 748 749 /* TLS IE dynamic relocations. */ 750 EMPTY_HOWTO (R_MIPS_TLS_TPREL32), 751 752 HOWTO (R_MIPS_TLS_TPREL64, /* type */ 753 0, /* rightshift */ 754 4, /* size (0 = byte, 1 = short, 2 = long) */ 755 64, /* bitsize */ 756 FALSE, /* pc_relative */ 757 0, /* bitpos */ 758 complain_overflow_dont, /* complain_on_overflow */ 759 _bfd_mips_elf_generic_reloc, /* special_function */ 760 "R_MIPS_TLS_TPREL64", /* name */ 761 TRUE, /* partial_inplace */ 762 MINUS_ONE, /* src_mask */ 763 MINUS_ONE, /* dst_mask */ 764 FALSE), /* pcrel_offset */ 765 766 /* TLS thread pointer offset. */ 767 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */ 768 0, /* rightshift */ 769 2, /* size (0 = byte, 1 = short, 2 = long) */ 770 16, /* bitsize */ 771 FALSE, /* pc_relative */ 772 0, /* bitpos */ 773 complain_overflow_signed, /* complain_on_overflow */ 774 _bfd_mips_elf_generic_reloc, /* special_function */ 775 "R_MIPS_TLS_TPREL_HI16", /* name */ 776 TRUE, /* partial_inplace */ 777 0x0000ffff, /* src_mask */ 778 0x0000ffff, /* dst_mask */ 779 FALSE), /* pcrel_offset */ 780 781 /* TLS thread pointer offset. */ 782 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */ 783 0, /* rightshift */ 784 2, /* size (0 = byte, 1 = short, 2 = long) */ 785 16, /* bitsize */ 786 FALSE, /* pc_relative */ 787 0, /* bitpos */ 788 complain_overflow_signed, /* complain_on_overflow */ 789 _bfd_mips_elf_generic_reloc, /* special_function */ 790 "R_MIPS_TLS_TPREL_LO16", /* name */ 791 TRUE, /* partial_inplace */ 792 0x0000ffff, /* src_mask */ 793 0x0000ffff, /* dst_mask */ 794 FALSE), /* pcrel_offset */ 795 796 /* 32 bit relocation with no addend. */ 797 HOWTO (R_MIPS_GLOB_DAT, /* type */ 798 0, /* rightshift */ 799 2, /* size (0 = byte, 1 = short, 2 = long) */ 800 32, /* bitsize */ 801 FALSE, /* pc_relative */ 802 0, /* bitpos */ 803 complain_overflow_dont, /* complain_on_overflow */ 804 _bfd_mips_elf_generic_reloc, /* special_function */ 805 "R_MIPS_GLOB_DAT", /* name */ 806 FALSE, /* partial_inplace */ 807 0x0, /* src_mask */ 808 0xffffffff, /* dst_mask */ 809 FALSE), /* pcrel_offset */ 810 }; 811 812 /* The relocation table used for SHT_RELA sections. */ 813 814 static reloc_howto_type mips_elf64_howto_table_rela[] = 815 { 816 /* No relocation. */ 817 HOWTO (R_MIPS_NONE, /* type */ 818 0, /* rightshift */ 819 0, /* size (0 = byte, 1 = short, 2 = long) */ 820 0, /* bitsize */ 821 FALSE, /* pc_relative */ 822 0, /* bitpos */ 823 complain_overflow_dont, /* complain_on_overflow */ 824 _bfd_mips_elf_generic_reloc, /* special_function */ 825 "R_MIPS_NONE", /* name */ 826 FALSE, /* partial_inplace */ 827 0, /* src_mask */ 828 0, /* dst_mask */ 829 FALSE), /* pcrel_offset */ 830 831 /* 16 bit relocation. */ 832 HOWTO (R_MIPS_16, /* type */ 833 0, /* rightshift */ 834 2, /* size (0 = byte, 1 = short, 2 = long) */ 835 16, /* bitsize */ 836 FALSE, /* pc_relative */ 837 0, /* bitpos */ 838 complain_overflow_signed, /* complain_on_overflow */ 839 _bfd_mips_elf_generic_reloc, /* special_function */ 840 "R_MIPS_16", /* name */ 841 FALSE, /* partial_inplace */ 842 0, /* src_mask */ 843 0x0000ffff, /* dst_mask */ 844 FALSE), /* pcrel_offset */ 845 846 /* 32 bit relocation. */ 847 HOWTO (R_MIPS_32, /* type */ 848 0, /* rightshift */ 849 2, /* size (0 = byte, 1 = short, 2 = long) */ 850 32, /* bitsize */ 851 FALSE, /* pc_relative */ 852 0, /* bitpos */ 853 complain_overflow_dont, /* complain_on_overflow */ 854 _bfd_mips_elf_generic_reloc, /* special_function */ 855 "R_MIPS_32", /* name */ 856 FALSE, /* partial_inplace */ 857 0, /* src_mask */ 858 0xffffffff, /* dst_mask */ 859 FALSE), /* pcrel_offset */ 860 861 /* 32 bit symbol relative relocation. */ 862 HOWTO (R_MIPS_REL32, /* type */ 863 0, /* rightshift */ 864 2, /* size (0 = byte, 1 = short, 2 = long) */ 865 32, /* bitsize */ 866 FALSE, /* pc_relative */ 867 0, /* bitpos */ 868 complain_overflow_dont, /* complain_on_overflow */ 869 _bfd_mips_elf_generic_reloc, /* special_function */ 870 "R_MIPS_REL32", /* name */ 871 FALSE, /* partial_inplace */ 872 0, /* src_mask */ 873 0xffffffff, /* dst_mask */ 874 FALSE), /* pcrel_offset */ 875 876 /* 26 bit jump address. */ 877 HOWTO (R_MIPS_26, /* type */ 878 2, /* rightshift */ 879 2, /* size (0 = byte, 1 = short, 2 = long) */ 880 26, /* bitsize */ 881 FALSE, /* pc_relative */ 882 0, /* bitpos */ 883 complain_overflow_dont, /* complain_on_overflow */ 884 /* This needs complex overflow 885 detection, because the upper 36 886 bits must match the PC + 4. */ 887 _bfd_mips_elf_generic_reloc, /* special_function */ 888 "R_MIPS_26", /* name */ 889 FALSE, /* partial_inplace */ 890 0, /* src_mask */ 891 0x03ffffff, /* dst_mask */ 892 FALSE), /* pcrel_offset */ 893 894 /* High 16 bits of symbol value. */ 895 HOWTO (R_MIPS_HI16, /* type */ 896 0, /* rightshift */ 897 2, /* size (0 = byte, 1 = short, 2 = long) */ 898 16, /* bitsize */ 899 FALSE, /* pc_relative */ 900 0, /* bitpos */ 901 complain_overflow_dont, /* complain_on_overflow */ 902 _bfd_mips_elf_generic_reloc, /* special_function */ 903 "R_MIPS_HI16", /* name */ 904 FALSE, /* partial_inplace */ 905 0, /* src_mask */ 906 0x0000ffff, /* dst_mask */ 907 FALSE), /* pcrel_offset */ 908 909 /* Low 16 bits of symbol value. */ 910 HOWTO (R_MIPS_LO16, /* type */ 911 0, /* rightshift */ 912 2, /* size (0 = byte, 1 = short, 2 = long) */ 913 16, /* bitsize */ 914 FALSE, /* pc_relative */ 915 0, /* bitpos */ 916 complain_overflow_dont, /* complain_on_overflow */ 917 _bfd_mips_elf_generic_reloc, /* special_function */ 918 "R_MIPS_LO16", /* name */ 919 FALSE, /* partial_inplace */ 920 0, /* src_mask */ 921 0x0000ffff, /* dst_mask */ 922 FALSE), /* pcrel_offset */ 923 924 /* GP relative reference. */ 925 HOWTO (R_MIPS_GPREL16, /* type */ 926 0, /* rightshift */ 927 2, /* size (0 = byte, 1 = short, 2 = long) */ 928 16, /* bitsize */ 929 FALSE, /* pc_relative */ 930 0, /* bitpos */ 931 complain_overflow_signed, /* complain_on_overflow */ 932 mips_elf64_gprel16_reloc, /* special_function */ 933 "R_MIPS_GPREL16", /* name */ 934 FALSE, /* partial_inplace */ 935 0, /* src_mask */ 936 0x0000ffff, /* dst_mask */ 937 FALSE), /* pcrel_offset */ 938 939 /* Reference to literal section. */ 940 HOWTO (R_MIPS_LITERAL, /* type */ 941 0, /* rightshift */ 942 2, /* size (0 = byte, 1 = short, 2 = long) */ 943 16, /* bitsize */ 944 FALSE, /* pc_relative */ 945 0, /* bitpos */ 946 complain_overflow_signed, /* complain_on_overflow */ 947 mips_elf64_literal_reloc, /* special_function */ 948 "R_MIPS_LITERAL", /* name */ 949 FALSE, /* partial_inplace */ 950 0, /* src_mask */ 951 0x0000ffff, /* dst_mask */ 952 FALSE), /* pcrel_offset */ 953 954 /* Reference to global offset table. */ 955 HOWTO (R_MIPS_GOT16, /* type */ 956 0, /* rightshift */ 957 2, /* size (0 = byte, 1 = short, 2 = long) */ 958 16, /* bitsize */ 959 FALSE, /* pc_relative */ 960 0, /* bitpos */ 961 complain_overflow_signed, /* complain_on_overflow */ 962 _bfd_mips_elf_generic_reloc, /* special_function */ 963 "R_MIPS_GOT16", /* name */ 964 FALSE, /* partial_inplace */ 965 0, /* src_mask */ 966 0x0000ffff, /* dst_mask */ 967 FALSE), /* pcrel_offset */ 968 969 /* 16 bit PC relative reference. Note that the ABI document has a typo 970 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless. 971 We do the right thing here. */ 972 HOWTO (R_MIPS_PC16, /* type */ 973 2, /* rightshift */ 974 2, /* size (0 = byte, 1 = short, 2 = long) */ 975 16, /* bitsize */ 976 TRUE, /* pc_relative */ 977 0, /* bitpos */ 978 complain_overflow_signed, /* complain_on_overflow */ 979 _bfd_mips_elf_generic_reloc, /* special_function */ 980 "R_MIPS_PC16", /* name */ 981 FALSE, /* partial_inplace */ 982 0, /* src_mask */ 983 0x0000ffff, /* dst_mask */ 984 TRUE), /* pcrel_offset */ 985 986 /* 16 bit call through global offset table. */ 987 HOWTO (R_MIPS_CALL16, /* type */ 988 0, /* rightshift */ 989 2, /* size (0 = byte, 1 = short, 2 = long) */ 990 16, /* bitsize */ 991 FALSE, /* pc_relative */ 992 0, /* bitpos */ 993 complain_overflow_signed, /* complain_on_overflow */ 994 _bfd_mips_elf_generic_reloc, /* special_function */ 995 "R_MIPS_CALL16", /* name */ 996 FALSE, /* partial_inplace */ 997 0, /* src_mask */ 998 0x0000ffff, /* dst_mask */ 999 FALSE), /* pcrel_offset */ 1000 1001 /* 32 bit GP relative reference. */ 1002 HOWTO (R_MIPS_GPREL32, /* type */ 1003 0, /* rightshift */ 1004 2, /* size (0 = byte, 1 = short, 2 = long) */ 1005 32, /* bitsize */ 1006 FALSE, /* pc_relative */ 1007 0, /* bitpos */ 1008 complain_overflow_dont, /* complain_on_overflow */ 1009 mips_elf64_gprel32_reloc, /* special_function */ 1010 "R_MIPS_GPREL32", /* name */ 1011 FALSE, /* partial_inplace */ 1012 0, /* src_mask */ 1013 0xffffffff, /* dst_mask */ 1014 FALSE), /* pcrel_offset */ 1015 1016 EMPTY_HOWTO (13), 1017 EMPTY_HOWTO (14), 1018 EMPTY_HOWTO (15), 1019 1020 /* A 5 bit shift field. */ 1021 HOWTO (R_MIPS_SHIFT5, /* type */ 1022 0, /* rightshift */ 1023 2, /* size (0 = byte, 1 = short, 2 = long) */ 1024 5, /* bitsize */ 1025 FALSE, /* pc_relative */ 1026 6, /* bitpos */ 1027 complain_overflow_bitfield, /* complain_on_overflow */ 1028 _bfd_mips_elf_generic_reloc, /* special_function */ 1029 "R_MIPS_SHIFT5", /* name */ 1030 FALSE, /* partial_inplace */ 1031 0, /* src_mask */ 1032 0x000007c0, /* dst_mask */ 1033 FALSE), /* pcrel_offset */ 1034 1035 /* A 6 bit shift field. */ 1036 HOWTO (R_MIPS_SHIFT6, /* type */ 1037 0, /* rightshift */ 1038 2, /* size (0 = byte, 1 = short, 2 = long) */ 1039 6, /* bitsize */ 1040 FALSE, /* pc_relative */ 1041 6, /* bitpos */ 1042 complain_overflow_bitfield, /* complain_on_overflow */ 1043 mips_elf64_shift6_reloc, /* special_function */ 1044 "R_MIPS_SHIFT6", /* name */ 1045 FALSE, /* partial_inplace */ 1046 0, /* src_mask */ 1047 0x000007c4, /* dst_mask */ 1048 FALSE), /* pcrel_offset */ 1049 1050 /* 64 bit relocation. */ 1051 HOWTO (R_MIPS_64, /* type */ 1052 0, /* rightshift */ 1053 4, /* size (0 = byte, 1 = short, 2 = long) */ 1054 64, /* bitsize */ 1055 FALSE, /* pc_relative */ 1056 0, /* bitpos */ 1057 complain_overflow_dont, /* complain_on_overflow */ 1058 _bfd_mips_elf_generic_reloc, /* special_function */ 1059 "R_MIPS_64", /* name */ 1060 FALSE, /* partial_inplace */ 1061 0, /* src_mask */ 1062 MINUS_ONE, /* dst_mask */ 1063 FALSE), /* pcrel_offset */ 1064 1065 /* Displacement in the global offset table. */ 1066 HOWTO (R_MIPS_GOT_DISP, /* type */ 1067 0, /* rightshift */ 1068 2, /* size (0 = byte, 1 = short, 2 = long) */ 1069 16, /* bitsize */ 1070 FALSE, /* pc_relative */ 1071 0, /* bitpos */ 1072 complain_overflow_signed, /* complain_on_overflow */ 1073 _bfd_mips_elf_generic_reloc, /* special_function */ 1074 "R_MIPS_GOT_DISP", /* name */ 1075 FALSE, /* partial_inplace */ 1076 0, /* src_mask */ 1077 0x0000ffff, /* dst_mask */ 1078 FALSE), /* pcrel_offset */ 1079 1080 /* Displacement to page pointer in the global offset table. */ 1081 HOWTO (R_MIPS_GOT_PAGE, /* type */ 1082 0, /* rightshift */ 1083 2, /* size (0 = byte, 1 = short, 2 = long) */ 1084 16, /* bitsize */ 1085 FALSE, /* pc_relative */ 1086 0, /* bitpos */ 1087 complain_overflow_signed, /* complain_on_overflow */ 1088 _bfd_mips_elf_generic_reloc, /* special_function */ 1089 "R_MIPS_GOT_PAGE", /* name */ 1090 FALSE, /* partial_inplace */ 1091 0, /* src_mask */ 1092 0x0000ffff, /* dst_mask */ 1093 FALSE), /* pcrel_offset */ 1094 1095 /* Offset from page pointer in the global offset table. */ 1096 HOWTO (R_MIPS_GOT_OFST, /* type */ 1097 0, /* rightshift */ 1098 2, /* size (0 = byte, 1 = short, 2 = long) */ 1099 16, /* bitsize */ 1100 FALSE, /* pc_relative */ 1101 0, /* bitpos */ 1102 complain_overflow_signed, /* complain_on_overflow */ 1103 _bfd_mips_elf_generic_reloc, /* special_function */ 1104 "R_MIPS_GOT_OFST", /* name */ 1105 FALSE, /* partial_inplace */ 1106 0, /* src_mask */ 1107 0x0000ffff, /* dst_mask */ 1108 FALSE), /* pcrel_offset */ 1109 1110 /* High 16 bits of displacement in global offset table. */ 1111 HOWTO (R_MIPS_GOT_HI16, /* type */ 1112 0, /* rightshift */ 1113 2, /* size (0 = byte, 1 = short, 2 = long) */ 1114 16, /* bitsize */ 1115 FALSE, /* pc_relative */ 1116 0, /* bitpos */ 1117 complain_overflow_dont, /* complain_on_overflow */ 1118 _bfd_mips_elf_generic_reloc, /* special_function */ 1119 "R_MIPS_GOT_HI16", /* name */ 1120 FALSE, /* partial_inplace */ 1121 0, /* src_mask */ 1122 0x0000ffff, /* dst_mask */ 1123 FALSE), /* pcrel_offset */ 1124 1125 /* Low 16 bits of displacement in global offset table. */ 1126 HOWTO (R_MIPS_GOT_LO16, /* type */ 1127 0, /* rightshift */ 1128 2, /* size (0 = byte, 1 = short, 2 = long) */ 1129 16, /* bitsize */ 1130 FALSE, /* pc_relative */ 1131 0, /* bitpos */ 1132 complain_overflow_dont, /* complain_on_overflow */ 1133 _bfd_mips_elf_generic_reloc, /* special_function */ 1134 "R_MIPS_GOT_LO16", /* name */ 1135 FALSE, /* partial_inplace */ 1136 0, /* src_mask */ 1137 0x0000ffff, /* dst_mask */ 1138 FALSE), /* pcrel_offset */ 1139 1140 /* 64 bit subtraction. */ 1141 HOWTO (R_MIPS_SUB, /* type */ 1142 0, /* rightshift */ 1143 4, /* size (0 = byte, 1 = short, 2 = long) */ 1144 64, /* bitsize */ 1145 FALSE, /* pc_relative */ 1146 0, /* bitpos */ 1147 complain_overflow_dont, /* complain_on_overflow */ 1148 _bfd_mips_elf_generic_reloc, /* special_function */ 1149 "R_MIPS_SUB", /* name */ 1150 FALSE, /* partial_inplace */ 1151 0, /* src_mask */ 1152 MINUS_ONE, /* dst_mask */ 1153 FALSE), /* pcrel_offset */ 1154 1155 /* Insert the addend as an instruction. */ 1156 /* FIXME: Not handled correctly. */ 1157 HOWTO (R_MIPS_INSERT_A, /* type */ 1158 0, /* rightshift */ 1159 2, /* size (0 = byte, 1 = short, 2 = long) */ 1160 32, /* bitsize */ 1161 FALSE, /* pc_relative */ 1162 0, /* bitpos */ 1163 complain_overflow_dont, /* complain_on_overflow */ 1164 _bfd_mips_elf_generic_reloc, /* special_function */ 1165 "R_MIPS_INSERT_A", /* name */ 1166 FALSE, /* partial_inplace */ 1167 0, /* src_mask */ 1168 0xffffffff, /* dst_mask */ 1169 FALSE), /* pcrel_offset */ 1170 1171 /* Insert the addend as an instruction, and change all relocations 1172 to refer to the old instruction at the address. */ 1173 /* FIXME: Not handled correctly. */ 1174 HOWTO (R_MIPS_INSERT_B, /* type */ 1175 0, /* rightshift */ 1176 2, /* size (0 = byte, 1 = short, 2 = long) */ 1177 32, /* bitsize */ 1178 FALSE, /* pc_relative */ 1179 0, /* bitpos */ 1180 complain_overflow_dont, /* complain_on_overflow */ 1181 _bfd_mips_elf_generic_reloc, /* special_function */ 1182 "R_MIPS_INSERT_B", /* name */ 1183 FALSE, /* partial_inplace */ 1184 0, /* src_mask */ 1185 0xffffffff, /* dst_mask */ 1186 FALSE), /* pcrel_offset */ 1187 1188 /* Delete a 32 bit instruction. */ 1189 /* FIXME: Not handled correctly. */ 1190 HOWTO (R_MIPS_DELETE, /* type */ 1191 0, /* rightshift */ 1192 2, /* size (0 = byte, 1 = short, 2 = long) */ 1193 32, /* bitsize */ 1194 FALSE, /* pc_relative */ 1195 0, /* bitpos */ 1196 complain_overflow_dont, /* complain_on_overflow */ 1197 _bfd_mips_elf_generic_reloc, /* special_function */ 1198 "R_MIPS_DELETE", /* name */ 1199 FALSE, /* partial_inplace */ 1200 0, /* src_mask */ 1201 0xffffffff, /* dst_mask */ 1202 FALSE), /* pcrel_offset */ 1203 1204 /* Get the higher value of a 64 bit addend. */ 1205 HOWTO (R_MIPS_HIGHER, /* type */ 1206 0, /* rightshift */ 1207 2, /* size (0 = byte, 1 = short, 2 = long) */ 1208 16, /* bitsize */ 1209 FALSE, /* pc_relative */ 1210 0, /* bitpos */ 1211 complain_overflow_dont, /* complain_on_overflow */ 1212 _bfd_mips_elf_generic_reloc, /* special_function */ 1213 "R_MIPS_HIGHER", /* name */ 1214 FALSE, /* partial_inplace */ 1215 0, /* src_mask */ 1216 0x0000ffff, /* dst_mask */ 1217 FALSE), /* pcrel_offset */ 1218 1219 /* Get the highest value of a 64 bit addend. */ 1220 HOWTO (R_MIPS_HIGHEST, /* type */ 1221 0, /* rightshift */ 1222 2, /* size (0 = byte, 1 = short, 2 = long) */ 1223 16, /* bitsize */ 1224 FALSE, /* pc_relative */ 1225 0, /* bitpos */ 1226 complain_overflow_dont, /* complain_on_overflow */ 1227 _bfd_mips_elf_generic_reloc, /* special_function */ 1228 "R_MIPS_HIGHEST", /* name */ 1229 FALSE, /* partial_inplace */ 1230 0, /* src_mask */ 1231 0x0000ffff, /* dst_mask */ 1232 FALSE), /* pcrel_offset */ 1233 1234 /* High 16 bits of displacement in global offset table. */ 1235 HOWTO (R_MIPS_CALL_HI16, /* type */ 1236 0, /* rightshift */ 1237 2, /* size (0 = byte, 1 = short, 2 = long) */ 1238 16, /* bitsize */ 1239 FALSE, /* pc_relative */ 1240 0, /* bitpos */ 1241 complain_overflow_dont, /* complain_on_overflow */ 1242 _bfd_mips_elf_generic_reloc, /* special_function */ 1243 "R_MIPS_CALL_HI16", /* name */ 1244 FALSE, /* partial_inplace */ 1245 0, /* src_mask */ 1246 0x0000ffff, /* dst_mask */ 1247 FALSE), /* pcrel_offset */ 1248 1249 /* Low 16 bits of displacement in global offset table. */ 1250 HOWTO (R_MIPS_CALL_LO16, /* type */ 1251 0, /* rightshift */ 1252 2, /* size (0 = byte, 1 = short, 2 = long) */ 1253 16, /* bitsize */ 1254 FALSE, /* pc_relative */ 1255 0, /* bitpos */ 1256 complain_overflow_dont, /* complain_on_overflow */ 1257 _bfd_mips_elf_generic_reloc, /* special_function */ 1258 "R_MIPS_CALL_LO16", /* name */ 1259 FALSE, /* partial_inplace */ 1260 0, /* src_mask */ 1261 0x0000ffff, /* dst_mask */ 1262 FALSE), /* pcrel_offset */ 1263 1264 /* Section displacement, used by an associated event location section. */ 1265 HOWTO (R_MIPS_SCN_DISP, /* type */ 1266 0, /* rightshift */ 1267 2, /* size (0 = byte, 1 = short, 2 = long) */ 1268 32, /* bitsize */ 1269 FALSE, /* pc_relative */ 1270 0, /* bitpos */ 1271 complain_overflow_dont, /* complain_on_overflow */ 1272 _bfd_mips_elf_generic_reloc, /* special_function */ 1273 "R_MIPS_SCN_DISP", /* name */ 1274 FALSE, /* partial_inplace */ 1275 0, /* src_mask */ 1276 0xffffffff, /* dst_mask */ 1277 FALSE), /* pcrel_offset */ 1278 1279 HOWTO (R_MIPS_REL16, /* type */ 1280 0, /* rightshift */ 1281 1, /* size (0 = byte, 1 = short, 2 = long) */ 1282 16, /* bitsize */ 1283 FALSE, /* pc_relative */ 1284 0, /* bitpos */ 1285 complain_overflow_signed, /* complain_on_overflow */ 1286 _bfd_mips_elf_generic_reloc, /* special_function */ 1287 "R_MIPS_REL16", /* name */ 1288 FALSE, /* partial_inplace */ 1289 0, /* src_mask */ 1290 0xffff, /* dst_mask */ 1291 FALSE), /* pcrel_offset */ 1292 1293 /* These two are obsolete. */ 1294 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE), 1295 EMPTY_HOWTO (R_MIPS_PJUMP), 1296 1297 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section. 1298 It must be used for multigot GOT's (and only there). */ 1299 HOWTO (R_MIPS_RELGOT, /* type */ 1300 0, /* rightshift */ 1301 2, /* size (0 = byte, 1 = short, 2 = long) */ 1302 32, /* bitsize */ 1303 FALSE, /* pc_relative */ 1304 0, /* bitpos */ 1305 complain_overflow_dont, /* complain_on_overflow */ 1306 _bfd_mips_elf_generic_reloc, /* special_function */ 1307 "R_MIPS_RELGOT", /* name */ 1308 FALSE, /* partial_inplace */ 1309 0, /* src_mask */ 1310 0xffffffff, /* dst_mask */ 1311 FALSE), /* pcrel_offset */ 1312 1313 /* Protected jump conversion. This is an optimization hint. No 1314 relocation is required for correctness. */ 1315 HOWTO (R_MIPS_JALR, /* type */ 1316 0, /* rightshift */ 1317 2, /* size (0 = byte, 1 = short, 2 = long) */ 1318 32, /* bitsize */ 1319 FALSE, /* pc_relative */ 1320 0, /* bitpos */ 1321 complain_overflow_dont, /* complain_on_overflow */ 1322 _bfd_mips_elf_generic_reloc, /* special_function */ 1323 "R_MIPS_JALR", /* name */ 1324 FALSE, /* partial_inplace */ 1325 0, /* src_mask */ 1326 0x00000000, /* dst_mask */ 1327 FALSE), /* pcrel_offset */ 1328 1329 /* TLS relocations. */ 1330 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32), 1331 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32), 1332 1333 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */ 1334 0, /* rightshift */ 1335 4, /* size (0 = byte, 1 = short, 2 = long) */ 1336 64, /* bitsize */ 1337 FALSE, /* pc_relative */ 1338 0, /* bitpos */ 1339 complain_overflow_dont, /* complain_on_overflow */ 1340 _bfd_mips_elf_generic_reloc, /* special_function */ 1341 "R_MIPS_TLS_DTPMOD64", /* name */ 1342 FALSE, /* partial_inplace */ 1343 MINUS_ONE, /* src_mask */ 1344 MINUS_ONE, /* dst_mask */ 1345 FALSE), /* pcrel_offset */ 1346 1347 HOWTO (R_MIPS_TLS_DTPREL64, /* type */ 1348 0, /* rightshift */ 1349 4, /* size (0 = byte, 1 = short, 2 = long) */ 1350 64, /* bitsize */ 1351 FALSE, /* pc_relative */ 1352 0, /* bitpos */ 1353 complain_overflow_dont, /* complain_on_overflow */ 1354 _bfd_mips_elf_generic_reloc, /* special_function */ 1355 "R_MIPS_TLS_DTPREL64", /* name */ 1356 FALSE, /* partial_inplace */ 1357 MINUS_ONE, /* src_mask */ 1358 MINUS_ONE, /* dst_mask */ 1359 FALSE), /* pcrel_offset */ 1360 1361 /* TLS general dynamic variable reference. */ 1362 HOWTO (R_MIPS_TLS_GD, /* type */ 1363 0, /* rightshift */ 1364 2, /* size (0 = byte, 1 = short, 2 = long) */ 1365 16, /* bitsize */ 1366 FALSE, /* pc_relative */ 1367 0, /* bitpos */ 1368 complain_overflow_signed, /* complain_on_overflow */ 1369 _bfd_mips_elf_generic_reloc, /* special_function */ 1370 "R_MIPS_TLS_GD", /* name */ 1371 FALSE, /* partial_inplace */ 1372 0x0000ffff, /* src_mask */ 1373 0x0000ffff, /* dst_mask */ 1374 FALSE), /* pcrel_offset */ 1375 1376 /* TLS local dynamic variable reference. */ 1377 HOWTO (R_MIPS_TLS_LDM, /* type */ 1378 0, /* rightshift */ 1379 2, /* size (0 = byte, 1 = short, 2 = long) */ 1380 16, /* bitsize */ 1381 FALSE, /* pc_relative */ 1382 0, /* bitpos */ 1383 complain_overflow_signed, /* complain_on_overflow */ 1384 _bfd_mips_elf_generic_reloc, /* special_function */ 1385 "R_MIPS_TLS_LDM", /* name */ 1386 FALSE, /* partial_inplace */ 1387 0x0000ffff, /* src_mask */ 1388 0x0000ffff, /* dst_mask */ 1389 FALSE), /* pcrel_offset */ 1390 1391 /* TLS local dynamic offset. */ 1392 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */ 1393 0, /* rightshift */ 1394 2, /* size (0 = byte, 1 = short, 2 = long) */ 1395 16, /* bitsize */ 1396 FALSE, /* pc_relative */ 1397 0, /* bitpos */ 1398 complain_overflow_signed, /* complain_on_overflow */ 1399 _bfd_mips_elf_generic_reloc, /* special_function */ 1400 "R_MIPS_TLS_DTPREL_HI16", /* name */ 1401 FALSE, /* partial_inplace */ 1402 0x0000ffff, /* src_mask */ 1403 0x0000ffff, /* dst_mask */ 1404 FALSE), /* pcrel_offset */ 1405 1406 /* TLS local dynamic offset. */ 1407 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */ 1408 0, /* rightshift */ 1409 2, /* size (0 = byte, 1 = short, 2 = long) */ 1410 16, /* bitsize */ 1411 FALSE, /* pc_relative */ 1412 0, /* bitpos */ 1413 complain_overflow_signed, /* complain_on_overflow */ 1414 _bfd_mips_elf_generic_reloc, /* special_function */ 1415 "R_MIPS_TLS_DTPREL_LO16", /* name */ 1416 FALSE, /* partial_inplace */ 1417 0x0000ffff, /* src_mask */ 1418 0x0000ffff, /* dst_mask */ 1419 FALSE), /* pcrel_offset */ 1420 1421 /* TLS thread pointer offset. */ 1422 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */ 1423 0, /* rightshift */ 1424 2, /* size (0 = byte, 1 = short, 2 = long) */ 1425 16, /* bitsize */ 1426 FALSE, /* pc_relative */ 1427 0, /* bitpos */ 1428 complain_overflow_signed, /* complain_on_overflow */ 1429 _bfd_mips_elf_generic_reloc, /* special_function */ 1430 "R_MIPS_TLS_GOTTPREL", /* name */ 1431 FALSE, /* partial_inplace */ 1432 0x0000ffff, /* src_mask */ 1433 0x0000ffff, /* dst_mask */ 1434 FALSE), /* pcrel_offset */ 1435 1436 /* TLS IE dynamic relocations. */ 1437 EMPTY_HOWTO (R_MIPS_TLS_TPREL32), 1438 1439 HOWTO (R_MIPS_TLS_TPREL64, /* type */ 1440 0, /* rightshift */ 1441 4, /* size (0 = byte, 1 = short, 2 = long) */ 1442 64, /* bitsize */ 1443 FALSE, /* pc_relative */ 1444 0, /* bitpos */ 1445 complain_overflow_dont, /* complain_on_overflow */ 1446 _bfd_mips_elf_generic_reloc, /* special_function */ 1447 "R_MIPS_TLS_TPREL64", /* name */ 1448 FALSE, /* partial_inplace */ 1449 MINUS_ONE, /* src_mask */ 1450 MINUS_ONE, /* dst_mask */ 1451 FALSE), /* pcrel_offset */ 1452 1453 /* TLS thread pointer offset. */ 1454 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */ 1455 0, /* rightshift */ 1456 2, /* size (0 = byte, 1 = short, 2 = long) */ 1457 16, /* bitsize */ 1458 FALSE, /* pc_relative */ 1459 0, /* bitpos */ 1460 complain_overflow_signed, /* complain_on_overflow */ 1461 _bfd_mips_elf_generic_reloc, /* special_function */ 1462 "R_MIPS_TLS_TPREL_HI16", /* name */ 1463 FALSE, /* partial_inplace */ 1464 0x0000ffff, /* src_mask */ 1465 0x0000ffff, /* dst_mask */ 1466 FALSE), /* pcrel_offset */ 1467 1468 /* TLS thread pointer offset. */ 1469 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */ 1470 0, /* rightshift */ 1471 2, /* size (0 = byte, 1 = short, 2 = long) */ 1472 16, /* bitsize */ 1473 FALSE, /* pc_relative */ 1474 0, /* bitpos */ 1475 complain_overflow_signed, /* complain_on_overflow */ 1476 _bfd_mips_elf_generic_reloc, /* special_function */ 1477 "R_MIPS_TLS_TPREL_LO16", /* name */ 1478 FALSE, /* partial_inplace */ 1479 0x0000ffff, /* src_mask */ 1480 0x0000ffff, /* dst_mask */ 1481 FALSE), /* pcrel_offset */ 1482 1483 /* 32 bit relocation with no addend. */ 1484 HOWTO (R_MIPS_GLOB_DAT, /* type */ 1485 0, /* rightshift */ 1486 2, /* size (0 = byte, 1 = short, 2 = long) */ 1487 32, /* bitsize */ 1488 FALSE, /* pc_relative */ 1489 0, /* bitpos */ 1490 complain_overflow_dont, /* complain_on_overflow */ 1491 _bfd_mips_elf_generic_reloc, /* special_function */ 1492 "R_MIPS_GLOB_DAT", /* name */ 1493 FALSE, /* partial_inplace */ 1494 0x0, /* src_mask */ 1495 0xffffffff, /* dst_mask */ 1496 FALSE), /* pcrel_offset */ 1497 }; 1498 1499 static reloc_howto_type mips16_elf64_howto_table_rel[] = 1500 { 1501 /* The reloc used for the mips16 jump instruction. */ 1502 HOWTO (R_MIPS16_26, /* type */ 1503 2, /* rightshift */ 1504 2, /* size (0 = byte, 1 = short, 2 = long) */ 1505 26, /* bitsize */ 1506 FALSE, /* pc_relative */ 1507 0, /* bitpos */ 1508 complain_overflow_dont, /* complain_on_overflow */ 1509 /* This needs complex overflow 1510 detection, because the upper four 1511 bits must match the PC. */ 1512 _bfd_mips_elf_generic_reloc, /* special_function */ 1513 "R_MIPS16_26", /* name */ 1514 TRUE, /* partial_inplace */ 1515 0x3ffffff, /* src_mask */ 1516 0x3ffffff, /* dst_mask */ 1517 FALSE), /* pcrel_offset */ 1518 1519 /* The reloc used for the mips16 gprel instruction. */ 1520 HOWTO (R_MIPS16_GPREL, /* type */ 1521 0, /* rightshift */ 1522 2, /* size (0 = byte, 1 = short, 2 = long) */ 1523 16, /* bitsize */ 1524 FALSE, /* pc_relative */ 1525 0, /* bitpos */ 1526 complain_overflow_signed, /* complain_on_overflow */ 1527 mips16_gprel_reloc, /* special_function */ 1528 "R_MIPS16_GPREL", /* name */ 1529 TRUE, /* partial_inplace */ 1530 0x0000ffff, /* src_mask */ 1531 0x0000ffff, /* dst_mask */ 1532 FALSE), /* pcrel_offset */ 1533 1534 /* A MIPS16 reference to the global offset table. */ 1535 HOWTO (R_MIPS16_GOT16, /* type */ 1536 0, /* rightshift */ 1537 2, /* size (0 = byte, 1 = short, 2 = long) */ 1538 16, /* bitsize */ 1539 FALSE, /* pc_relative */ 1540 0, /* bitpos */ 1541 complain_overflow_dont, /* complain_on_overflow */ 1542 _bfd_mips_elf_got16_reloc, /* special_function */ 1543 "R_MIPS16_GOT16", /* name */ 1544 TRUE, /* partial_inplace */ 1545 0x0000ffff, /* src_mask */ 1546 0x0000ffff, /* dst_mask */ 1547 FALSE), /* pcrel_offset */ 1548 1549 /* A MIPS16 call through the global offset table. */ 1550 HOWTO (R_MIPS16_CALL16, /* type */ 1551 0, /* rightshift */ 1552 2, /* size (0 = byte, 1 = short, 2 = long) */ 1553 16, /* bitsize */ 1554 FALSE, /* pc_relative */ 1555 0, /* bitpos */ 1556 complain_overflow_dont, /* complain_on_overflow */ 1557 _bfd_mips_elf_generic_reloc, /* special_function */ 1558 "R_MIPS16_CALL16", /* name */ 1559 TRUE, /* partial_inplace */ 1560 0x0000ffff, /* src_mask */ 1561 0x0000ffff, /* dst_mask */ 1562 FALSE), /* pcrel_offset */ 1563 1564 /* MIPS16 high 16 bits of symbol value. */ 1565 HOWTO (R_MIPS16_HI16, /* type */ 1566 16, /* rightshift */ 1567 2, /* size (0 = byte, 1 = short, 2 = long) */ 1568 16, /* bitsize */ 1569 FALSE, /* pc_relative */ 1570 0, /* bitpos */ 1571 complain_overflow_dont, /* complain_on_overflow */ 1572 _bfd_mips_elf_hi16_reloc, /* special_function */ 1573 "R_MIPS16_HI16", /* name */ 1574 TRUE, /* partial_inplace */ 1575 0x0000ffff, /* src_mask */ 1576 0x0000ffff, /* dst_mask */ 1577 FALSE), /* pcrel_offset */ 1578 1579 /* MIPS16 low 16 bits of symbol value. */ 1580 HOWTO (R_MIPS16_LO16, /* type */ 1581 0, /* rightshift */ 1582 2, /* size (0 = byte, 1 = short, 2 = long) */ 1583 16, /* bitsize */ 1584 FALSE, /* pc_relative */ 1585 0, /* bitpos */ 1586 complain_overflow_dont, /* complain_on_overflow */ 1587 _bfd_mips_elf_lo16_reloc, /* special_function */ 1588 "R_MIPS16_LO16", /* name */ 1589 TRUE, /* partial_inplace */ 1590 0x0000ffff, /* src_mask */ 1591 0x0000ffff, /* dst_mask */ 1592 FALSE), /* pcrel_offset */ 1593 }; 1594 1595 static reloc_howto_type mips16_elf64_howto_table_rela[] = 1596 { 1597 /* The reloc used for the mips16 jump instruction. */ 1598 HOWTO (R_MIPS16_26, /* type */ 1599 2, /* rightshift */ 1600 2, /* size (0 = byte, 1 = short, 2 = long) */ 1601 26, /* bitsize */ 1602 FALSE, /* pc_relative */ 1603 0, /* bitpos */ 1604 complain_overflow_dont, /* complain_on_overflow */ 1605 /* This needs complex overflow 1606 detection, because the upper four 1607 bits must match the PC. */ 1608 _bfd_mips_elf_generic_reloc, /* special_function */ 1609 "R_MIPS16_26", /* name */ 1610 FALSE, /* partial_inplace */ 1611 0x3ffffff, /* src_mask */ 1612 0x3ffffff, /* dst_mask */ 1613 FALSE), /* pcrel_offset */ 1614 1615 /* The reloc used for the mips16 gprel instruction. */ 1616 HOWTO (R_MIPS16_GPREL, /* type */ 1617 0, /* rightshift */ 1618 2, /* size (0 = byte, 1 = short, 2 = long) */ 1619 16, /* bitsize */ 1620 FALSE, /* pc_relative */ 1621 0, /* bitpos */ 1622 complain_overflow_signed, /* complain_on_overflow */ 1623 mips16_gprel_reloc, /* special_function */ 1624 "R_MIPS16_GPREL", /* name */ 1625 FALSE, /* partial_inplace */ 1626 0x0000ffff, /* src_mask */ 1627 0x0000ffff, /* dst_mask */ 1628 FALSE), /* pcrel_offset */ 1629 1630 /* A MIPS16 reference to the global offset table. */ 1631 HOWTO (R_MIPS16_GOT16, /* type */ 1632 0, /* rightshift */ 1633 2, /* size (0 = byte, 1 = short, 2 = long) */ 1634 16, /* bitsize */ 1635 FALSE, /* pc_relative */ 1636 0, /* bitpos */ 1637 complain_overflow_dont, /* complain_on_overflow */ 1638 _bfd_mips_elf_got16_reloc, /* special_function */ 1639 "R_MIPS16_GOT16", /* name */ 1640 FALSE, /* partial_inplace */ 1641 0x0000ffff, /* src_mask */ 1642 0x0000ffff, /* dst_mask */ 1643 FALSE), /* pcrel_offset */ 1644 1645 /* A MIPS16 call through the global offset table. */ 1646 HOWTO (R_MIPS16_CALL16, /* type */ 1647 0, /* rightshift */ 1648 2, /* size (0 = byte, 1 = short, 2 = long) */ 1649 16, /* bitsize */ 1650 FALSE, /* pc_relative */ 1651 0, /* bitpos */ 1652 complain_overflow_dont, /* complain_on_overflow */ 1653 _bfd_mips_elf_generic_reloc, /* special_function */ 1654 "R_MIPS16_CALL16", /* name */ 1655 FALSE, /* partial_inplace */ 1656 0x0000ffff, /* src_mask */ 1657 0x0000ffff, /* dst_mask */ 1658 FALSE), /* pcrel_offset */ 1659 1660 /* MIPS16 high 16 bits of symbol value. */ 1661 HOWTO (R_MIPS16_HI16, /* type */ 1662 16, /* rightshift */ 1663 2, /* size (0 = byte, 1 = short, 2 = long) */ 1664 16, /* bitsize */ 1665 FALSE, /* pc_relative */ 1666 0, /* bitpos */ 1667 complain_overflow_dont, /* complain_on_overflow */ 1668 _bfd_mips_elf_hi16_reloc, /* special_function */ 1669 "R_MIPS16_HI16", /* name */ 1670 FALSE, /* partial_inplace */ 1671 0x0000ffff, /* src_mask */ 1672 0x0000ffff, /* dst_mask */ 1673 FALSE), /* pcrel_offset */ 1674 1675 /* MIPS16 low 16 bits of symbol value. */ 1676 HOWTO (R_MIPS16_LO16, /* type */ 1677 0, /* rightshift */ 1678 2, /* size (0 = byte, 1 = short, 2 = long) */ 1679 16, /* bitsize */ 1680 FALSE, /* pc_relative */ 1681 0, /* bitpos */ 1682 complain_overflow_dont, /* complain_on_overflow */ 1683 _bfd_mips_elf_lo16_reloc, /* special_function */ 1684 "R_MIPS16_LO16", /* name */ 1685 FALSE, /* partial_inplace */ 1686 0x0000ffff, /* src_mask */ 1687 0x0000ffff, /* dst_mask */ 1688 FALSE), /* pcrel_offset */ 1689 }; 1690 1691 /* GNU extension to record C++ vtable hierarchy */ 1692 static reloc_howto_type elf_mips_gnu_vtinherit_howto = 1693 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */ 1694 0, /* rightshift */ 1695 2, /* size (0 = byte, 1 = short, 2 = long) */ 1696 0, /* bitsize */ 1697 FALSE, /* pc_relative */ 1698 0, /* bitpos */ 1699 complain_overflow_dont, /* complain_on_overflow */ 1700 NULL, /* special_function */ 1701 "R_MIPS_GNU_VTINHERIT", /* name */ 1702 FALSE, /* partial_inplace */ 1703 0, /* src_mask */ 1704 0, /* dst_mask */ 1705 FALSE); /* pcrel_offset */ 1706 1707 /* GNU extension to record C++ vtable member usage */ 1708 static reloc_howto_type elf_mips_gnu_vtentry_howto = 1709 HOWTO (R_MIPS_GNU_VTENTRY, /* type */ 1710 0, /* rightshift */ 1711 2, /* size (0 = byte, 1 = short, 2 = long) */ 1712 0, /* bitsize */ 1713 FALSE, /* pc_relative */ 1714 0, /* bitpos */ 1715 complain_overflow_dont, /* complain_on_overflow */ 1716 _bfd_elf_rel_vtable_reloc_fn, /* special_function */ 1717 "R_MIPS_GNU_VTENTRY", /* name */ 1718 FALSE, /* partial_inplace */ 1719 0, /* src_mask */ 1720 0, /* dst_mask */ 1721 FALSE); /* pcrel_offset */ 1722 1723 /* 16 bit offset for pc-relative branches. */ 1724 static reloc_howto_type elf_mips_gnu_rel16_s2 = 1725 HOWTO (R_MIPS_GNU_REL16_S2, /* type */ 1726 2, /* rightshift */ 1727 2, /* size (0 = byte, 1 = short, 2 = long) */ 1728 16, /* bitsize */ 1729 TRUE, /* pc_relative */ 1730 0, /* bitpos */ 1731 complain_overflow_signed, /* complain_on_overflow */ 1732 _bfd_mips_elf_generic_reloc, /* special_function */ 1733 "R_MIPS_GNU_REL16_S2", /* name */ 1734 TRUE, /* partial_inplace */ 1735 0x0000ffff, /* src_mask */ 1736 0x0000ffff, /* dst_mask */ 1737 TRUE); /* pcrel_offset */ 1738 1739 /* 16 bit offset for pc-relative branches. */ 1740 static reloc_howto_type elf_mips_gnu_rela16_s2 = 1741 HOWTO (R_MIPS_GNU_REL16_S2, /* type */ 1742 2, /* rightshift */ 1743 2, /* size (0 = byte, 1 = short, 2 = long) */ 1744 16, /* bitsize */ 1745 TRUE, /* pc_relative */ 1746 0, /* bitpos */ 1747 complain_overflow_signed, /* complain_on_overflow */ 1748 _bfd_mips_elf_generic_reloc, /* special_function */ 1749 "R_MIPS_GNU_REL16_S2", /* name */ 1750 FALSE, /* partial_inplace */ 1751 0, /* src_mask */ 1752 0x0000ffff, /* dst_mask */ 1753 TRUE); /* pcrel_offset */ 1754 1755 /* Originally a VxWorks extension, but now used for other systems too. */ 1756 static reloc_howto_type elf_mips_copy_howto = 1757 HOWTO (R_MIPS_COPY, /* type */ 1758 0, /* rightshift */ 1759 0, /* this one is variable size */ 1760 0, /* bitsize */ 1761 FALSE, /* pc_relative */ 1762 0, /* bitpos */ 1763 complain_overflow_bitfield, /* complain_on_overflow */ 1764 bfd_elf_generic_reloc, /* special_function */ 1765 "R_MIPS_COPY", /* name */ 1766 FALSE, /* partial_inplace */ 1767 0x0, /* src_mask */ 1768 0x0, /* dst_mask */ 1769 FALSE); /* pcrel_offset */ 1770 1771 /* Originally a VxWorks extension, but now used for other systems too. */ 1772 static reloc_howto_type elf_mips_jump_slot_howto = 1773 HOWTO (R_MIPS_JUMP_SLOT, /* type */ 1774 0, /* rightshift */ 1775 4, /* size (0 = byte, 1 = short, 2 = long) */ 1776 64, /* bitsize */ 1777 FALSE, /* pc_relative */ 1778 0, /* bitpos */ 1779 complain_overflow_bitfield, /* complain_on_overflow */ 1780 bfd_elf_generic_reloc, /* special_function */ 1781 "R_MIPS_JUMP_SLOT", /* name */ 1782 FALSE, /* partial_inplace */ 1783 0x0, /* src_mask */ 1784 0x0, /* dst_mask */ 1785 FALSE); /* pcrel_offset */ 1786 1787 /* Swap in a MIPS 64-bit Rel reloc. */ 1788 1789 static void 1790 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src, 1791 Elf64_Mips_Internal_Rela *dst) 1792 { 1793 dst->r_offset = H_GET_64 (abfd, src->r_offset); 1794 dst->r_sym = H_GET_32 (abfd, src->r_sym); 1795 dst->r_ssym = H_GET_8 (abfd, src->r_ssym); 1796 dst->r_type3 = H_GET_8 (abfd, src->r_type3); 1797 dst->r_type2 = H_GET_8 (abfd, src->r_type2); 1798 dst->r_type = H_GET_8 (abfd, src->r_type); 1799 dst->r_addend = 0; 1800 } 1801 1802 /* Swap in a MIPS 64-bit Rela reloc. */ 1803 1804 static void 1805 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src, 1806 Elf64_Mips_Internal_Rela *dst) 1807 { 1808 dst->r_offset = H_GET_64 (abfd, src->r_offset); 1809 dst->r_sym = H_GET_32 (abfd, src->r_sym); 1810 dst->r_ssym = H_GET_8 (abfd, src->r_ssym); 1811 dst->r_type3 = H_GET_8 (abfd, src->r_type3); 1812 dst->r_type2 = H_GET_8 (abfd, src->r_type2); 1813 dst->r_type = H_GET_8 (abfd, src->r_type); 1814 dst->r_addend = H_GET_S64 (abfd, src->r_addend); 1815 } 1816 1817 /* Swap out a MIPS 64-bit Rel reloc. */ 1818 1819 static void 1820 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src, 1821 Elf64_Mips_External_Rel *dst) 1822 { 1823 H_PUT_64 (abfd, src->r_offset, dst->r_offset); 1824 H_PUT_32 (abfd, src->r_sym, dst->r_sym); 1825 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym); 1826 H_PUT_8 (abfd, src->r_type3, dst->r_type3); 1827 H_PUT_8 (abfd, src->r_type2, dst->r_type2); 1828 H_PUT_8 (abfd, src->r_type, dst->r_type); 1829 } 1830 1831 /* Swap out a MIPS 64-bit Rela reloc. */ 1832 1833 static void 1834 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src, 1835 Elf64_Mips_External_Rela *dst) 1836 { 1837 H_PUT_64 (abfd, src->r_offset, dst->r_offset); 1838 H_PUT_32 (abfd, src->r_sym, dst->r_sym); 1839 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym); 1840 H_PUT_8 (abfd, src->r_type3, dst->r_type3); 1841 H_PUT_8 (abfd, src->r_type2, dst->r_type2); 1842 H_PUT_8 (abfd, src->r_type, dst->r_type); 1843 H_PUT_S64 (abfd, src->r_addend, dst->r_addend); 1844 } 1845 1846 /* Swap in a MIPS 64-bit Rel reloc. */ 1847 1848 static void 1849 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src, 1850 Elf_Internal_Rela *dst) 1851 { 1852 Elf64_Mips_Internal_Rela mirel; 1853 1854 mips_elf64_swap_reloc_in (abfd, 1855 (const Elf64_Mips_External_Rel *) src, 1856 &mirel); 1857 1858 dst[0].r_offset = mirel.r_offset; 1859 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type); 1860 dst[0].r_addend = 0; 1861 dst[1].r_offset = mirel.r_offset; 1862 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2); 1863 dst[1].r_addend = 0; 1864 dst[2].r_offset = mirel.r_offset; 1865 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3); 1866 dst[2].r_addend = 0; 1867 } 1868 1869 /* Swap in a MIPS 64-bit Rela reloc. */ 1870 1871 static void 1872 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src, 1873 Elf_Internal_Rela *dst) 1874 { 1875 Elf64_Mips_Internal_Rela mirela; 1876 1877 mips_elf64_swap_reloca_in (abfd, 1878 (const Elf64_Mips_External_Rela *) src, 1879 &mirela); 1880 1881 dst[0].r_offset = mirela.r_offset; 1882 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type); 1883 dst[0].r_addend = mirela.r_addend; 1884 dst[1].r_offset = mirela.r_offset; 1885 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2); 1886 dst[1].r_addend = 0; 1887 dst[2].r_offset = mirela.r_offset; 1888 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3); 1889 dst[2].r_addend = 0; 1890 } 1891 1892 /* Swap out a MIPS 64-bit Rel reloc. */ 1893 1894 static void 1895 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src, 1896 bfd_byte *dst) 1897 { 1898 Elf64_Mips_Internal_Rela mirel; 1899 1900 mirel.r_offset = src[0].r_offset; 1901 BFD_ASSERT(src[0].r_offset == src[1].r_offset); 1902 1903 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info); 1904 mirel.r_sym = ELF64_R_SYM (src[0].r_info); 1905 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info); 1906 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info); 1907 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info); 1908 1909 mips_elf64_swap_reloc_out (abfd, &mirel, 1910 (Elf64_Mips_External_Rel *) dst); 1911 } 1912 1913 /* Swap out a MIPS 64-bit Rela reloc. */ 1914 1915 static void 1916 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src, 1917 bfd_byte *dst) 1918 { 1919 Elf64_Mips_Internal_Rela mirela; 1920 1921 mirela.r_offset = src[0].r_offset; 1922 BFD_ASSERT(src[0].r_offset == src[1].r_offset); 1923 BFD_ASSERT(src[0].r_offset == src[2].r_offset); 1924 1925 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info); 1926 mirela.r_sym = ELF64_R_SYM (src[0].r_info); 1927 mirela.r_addend = src[0].r_addend; 1928 BFD_ASSERT(src[1].r_addend == 0); 1929 BFD_ASSERT(src[2].r_addend == 0); 1930 1931 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info); 1932 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info); 1933 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info); 1934 1935 mips_elf64_swap_reloca_out (abfd, &mirela, 1936 (Elf64_Mips_External_Rela *) dst); 1937 } 1938 1939 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a 1940 dangerous relocation. */ 1941 1942 static bfd_boolean 1943 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp) 1944 { 1945 unsigned int count; 1946 asymbol **sym; 1947 unsigned int i; 1948 1949 /* If we've already figured out what GP will be, just return it. */ 1950 *pgp = _bfd_get_gp_value (output_bfd); 1951 if (*pgp) 1952 return TRUE; 1953 1954 count = bfd_get_symcount (output_bfd); 1955 sym = bfd_get_outsymbols (output_bfd); 1956 1957 /* The linker script will have created a symbol named `_gp' with the 1958 appropriate value. */ 1959 if (sym == NULL) 1960 i = count; 1961 else 1962 { 1963 for (i = 0; i < count; i++, sym++) 1964 { 1965 register const char *name; 1966 1967 name = bfd_asymbol_name (*sym); 1968 if (*name == '_' && strcmp (name, "_gp") == 0) 1969 { 1970 *pgp = bfd_asymbol_value (*sym); 1971 _bfd_set_gp_value (output_bfd, *pgp); 1972 break; 1973 } 1974 } 1975 } 1976 1977 if (i >= count) 1978 { 1979 /* Only get the error once. */ 1980 *pgp = 4; 1981 _bfd_set_gp_value (output_bfd, *pgp); 1982 return FALSE; 1983 } 1984 1985 return TRUE; 1986 } 1987 1988 /* We have to figure out the gp value, so that we can adjust the 1989 symbol value correctly. We look up the symbol _gp in the output 1990 BFD. If we can't find it, we're stuck. We cache it in the ELF 1991 target data. We don't need to adjust the symbol value for an 1992 external symbol if we are producing relocatable output. */ 1993 1994 static bfd_reloc_status_type 1995 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable, 1996 char **error_message, bfd_vma *pgp) 1997 { 1998 if (bfd_is_und_section (symbol->section) 1999 && ! relocatable) 2000 { 2001 *pgp = 0; 2002 return bfd_reloc_undefined; 2003 } 2004 2005 *pgp = _bfd_get_gp_value (output_bfd); 2006 if (*pgp == 0 2007 && (! relocatable 2008 || (symbol->flags & BSF_SECTION_SYM) != 0)) 2009 { 2010 if (relocatable) 2011 { 2012 /* Make up a value. */ 2013 *pgp = symbol->section->output_section->vma /*+ 0x4000*/; 2014 _bfd_set_gp_value (output_bfd, *pgp); 2015 } 2016 else if (!mips_elf64_assign_gp (output_bfd, pgp)) 2017 { 2018 *error_message = 2019 (char *) _("GP relative relocation when _gp not defined"); 2020 return bfd_reloc_dangerous; 2021 } 2022 } 2023 2024 return bfd_reloc_ok; 2025 } 2026 2027 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must 2028 become the offset from the gp register. */ 2029 2030 static bfd_reloc_status_type 2031 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 2032 void *data, asection *input_section, bfd *output_bfd, 2033 char **error_message) 2034 { 2035 bfd_boolean relocatable; 2036 bfd_reloc_status_type ret; 2037 bfd_vma gp; 2038 2039 /* If we're relocating, and this is an external symbol, we don't want 2040 to change anything. */ 2041 if (output_bfd != NULL 2042 && (symbol->flags & BSF_SECTION_SYM) == 0 2043 && (symbol->flags & BSF_LOCAL) != 0) 2044 { 2045 reloc_entry->address += input_section->output_offset; 2046 return bfd_reloc_ok; 2047 } 2048 2049 if (output_bfd != NULL) 2050 relocatable = TRUE; 2051 else 2052 { 2053 relocatable = FALSE; 2054 output_bfd = symbol->section->output_section->owner; 2055 } 2056 2057 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message, 2058 &gp); 2059 if (ret != bfd_reloc_ok) 2060 return ret; 2061 2062 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, 2063 input_section, relocatable, 2064 data, gp); 2065 } 2066 2067 /* Do a R_MIPS_LITERAL relocation. */ 2068 2069 static bfd_reloc_status_type 2070 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 2071 void *data, asection *input_section, bfd *output_bfd, 2072 char **error_message) 2073 { 2074 bfd_boolean relocatable; 2075 bfd_reloc_status_type ret; 2076 bfd_vma gp; 2077 2078 /* R_MIPS_LITERAL relocations are defined for local symbols only. */ 2079 if (output_bfd != NULL 2080 && (symbol->flags & BSF_SECTION_SYM) == 0 2081 && (symbol->flags & BSF_LOCAL) != 0) 2082 { 2083 *error_message = (char *) 2084 _("literal relocation occurs for an external symbol"); 2085 return bfd_reloc_outofrange; 2086 } 2087 2088 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */ 2089 if (output_bfd != NULL) 2090 relocatable = TRUE; 2091 else 2092 { 2093 relocatable = FALSE; 2094 output_bfd = symbol->section->output_section->owner; 2095 } 2096 2097 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message, 2098 &gp); 2099 if (ret != bfd_reloc_ok) 2100 return ret; 2101 2102 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, 2103 input_section, relocatable, 2104 data, gp); 2105 } 2106 2107 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must 2108 become the offset from the gp register. */ 2109 2110 static bfd_reloc_status_type 2111 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 2112 void *data, asection *input_section, bfd *output_bfd, 2113 char **error_message) 2114 { 2115 bfd_boolean relocatable; 2116 bfd_reloc_status_type ret; 2117 bfd_vma gp; 2118 bfd_vma relocation; 2119 bfd_vma val; 2120 2121 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */ 2122 if (output_bfd != NULL 2123 && (symbol->flags & BSF_SECTION_SYM) == 0 2124 && (symbol->flags & BSF_LOCAL) != 0) 2125 { 2126 *error_message = (char *) 2127 _("32bits gp relative relocation occurs for an external symbol"); 2128 return bfd_reloc_outofrange; 2129 } 2130 2131 if (output_bfd != NULL) 2132 relocatable = TRUE; 2133 else 2134 { 2135 relocatable = FALSE; 2136 output_bfd = symbol->section->output_section->owner; 2137 } 2138 2139 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, 2140 error_message, &gp); 2141 if (ret != bfd_reloc_ok) 2142 return ret; 2143 2144 if (bfd_is_com_section (symbol->section)) 2145 relocation = 0; 2146 else 2147 relocation = symbol->value; 2148 2149 relocation += symbol->section->output_section->vma; 2150 relocation += symbol->section->output_offset; 2151 2152 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) 2153 return bfd_reloc_outofrange; 2154 2155 /* Set val to the offset into the section or symbol. */ 2156 val = reloc_entry->addend; 2157 2158 if (reloc_entry->howto->partial_inplace) 2159 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); 2160 2161 /* Adjust val for the final section location and GP value. If we 2162 are producing relocatable output, we don't want to do this for 2163 an external symbol. */ 2164 if (! relocatable 2165 || (symbol->flags & BSF_SECTION_SYM) != 0) 2166 val += relocation - gp; 2167 2168 if (reloc_entry->howto->partial_inplace) 2169 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address); 2170 else 2171 reloc_entry->addend = val; 2172 2173 if (relocatable) 2174 reloc_entry->address += input_section->output_offset; 2175 2176 return bfd_reloc_ok; 2177 } 2178 2179 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2, 2180 the rest is at bits 6-10. The bitpos already got right by the howto. */ 2181 2182 static bfd_reloc_status_type 2183 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 2184 void *data, asection *input_section, bfd *output_bfd, 2185 char **error_message) 2186 { 2187 if (reloc_entry->howto->partial_inplace) 2188 { 2189 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0) 2190 | (reloc_entry->addend & 0x00000800) >> 9); 2191 } 2192 2193 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, 2194 input_section, output_bfd, 2195 error_message); 2196 } 2197 2198 /* Handle a mips16 GP relative reloc. */ 2199 2200 static bfd_reloc_status_type 2201 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 2202 void *data, asection *input_section, bfd *output_bfd, 2203 char **error_message) 2204 { 2205 bfd_boolean relocatable; 2206 bfd_reloc_status_type ret; 2207 bfd_byte *location; 2208 bfd_vma gp; 2209 2210 /* If we're relocating, and this is an external symbol, we don't want 2211 to change anything. */ 2212 if (output_bfd != NULL 2213 && (symbol->flags & BSF_SECTION_SYM) == 0 2214 && (symbol->flags & BSF_LOCAL) != 0) 2215 { 2216 reloc_entry->address += input_section->output_offset; 2217 return bfd_reloc_ok; 2218 } 2219 2220 if (output_bfd != NULL) 2221 relocatable = TRUE; 2222 else 2223 { 2224 relocatable = FALSE; 2225 output_bfd = symbol->section->output_section->owner; 2226 } 2227 2228 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message, 2229 &gp); 2230 if (ret != bfd_reloc_ok) 2231 return ret; 2232 2233 location = (bfd_byte *) data + reloc_entry->address; 2234 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE, 2235 location); 2236 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, 2237 input_section, relocatable, 2238 data, gp); 2239 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable, 2240 location); 2241 2242 return ret; 2243 } 2244 2245 /* A mapping from BFD reloc types to MIPS ELF reloc types. */ 2246 2247 struct elf_reloc_map { 2248 bfd_reloc_code_real_type bfd_val; 2249 enum elf_mips_reloc_type elf_val; 2250 }; 2251 2252 static const struct elf_reloc_map mips_reloc_map[] = 2253 { 2254 { BFD_RELOC_NONE, R_MIPS_NONE }, 2255 { BFD_RELOC_16, R_MIPS_16 }, 2256 { BFD_RELOC_32, R_MIPS_32 }, 2257 /* There is no BFD reloc for R_MIPS_REL32. */ 2258 { BFD_RELOC_64, R_MIPS_64 }, 2259 { BFD_RELOC_CTOR, R_MIPS_64 }, 2260 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 }, 2261 { BFD_RELOC_HI16_S, R_MIPS_HI16 }, 2262 { BFD_RELOC_LO16, R_MIPS_LO16 }, 2263 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 }, 2264 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 }, 2265 { BFD_RELOC_MIPS_JMP, R_MIPS_26 }, 2266 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL }, 2267 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 }, 2268 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 }, 2269 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 }, 2270 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 }, 2271 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }, 2272 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE }, 2273 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST }, 2274 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 }, 2275 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 }, 2276 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB }, 2277 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A }, 2278 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B }, 2279 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE }, 2280 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST }, 2281 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER }, 2282 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 }, 2283 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 }, 2284 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP }, 2285 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 }, 2286 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */ 2287 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT }, 2288 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }, 2289 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 }, 2290 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 }, 2291 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 }, 2292 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 }, 2293 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD }, 2294 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM }, 2295 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 }, 2296 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 }, 2297 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL }, 2298 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 }, 2299 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 }, 2300 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 }, 2301 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 } 2302 }; 2303 2304 static const struct elf_reloc_map mips16_reloc_map[] = 2305 { 2306 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min }, 2307 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min }, 2308 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min }, 2309 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min }, 2310 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min }, 2311 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min }, 2312 }; 2313 2314 /* Given a BFD reloc type, return a howto structure. */ 2315 2316 static reloc_howto_type * 2317 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 2318 bfd_reloc_code_real_type code) 2319 { 2320 unsigned int i; 2321 /* FIXME: We default to RELA here instead of choosing the right 2322 relocation variant. */ 2323 reloc_howto_type *howto_table = mips_elf64_howto_table_rela; 2324 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela; 2325 2326 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); 2327 i++) 2328 { 2329 if (mips_reloc_map[i].bfd_val == code) 2330 return &howto_table[(int) mips_reloc_map[i].elf_val]; 2331 } 2332 2333 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map); 2334 i++) 2335 { 2336 if (mips16_reloc_map[i].bfd_val == code) 2337 return &howto16_table[(int) mips16_reloc_map[i].elf_val]; 2338 } 2339 2340 switch (code) 2341 { 2342 case BFD_RELOC_VTABLE_INHERIT: 2343 return &elf_mips_gnu_vtinherit_howto; 2344 case BFD_RELOC_VTABLE_ENTRY: 2345 return &elf_mips_gnu_vtentry_howto; 2346 case BFD_RELOC_MIPS_COPY: 2347 return &elf_mips_copy_howto; 2348 case BFD_RELOC_MIPS_JUMP_SLOT: 2349 return &elf_mips_jump_slot_howto; 2350 default: 2351 bfd_set_error (bfd_error_bad_value); 2352 return NULL; 2353 } 2354 } 2355 2356 static reloc_howto_type * 2357 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 2358 const char *r_name) 2359 { 2360 unsigned int i; 2361 2362 for (i = 0; 2363 i < (sizeof (mips_elf64_howto_table_rela) 2364 / sizeof (mips_elf64_howto_table_rela[0])); i++) 2365 if (mips_elf64_howto_table_rela[i].name != NULL 2366 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0) 2367 return &mips_elf64_howto_table_rela[i]; 2368 2369 for (i = 0; 2370 i < (sizeof (mips16_elf64_howto_table_rela) 2371 / sizeof (mips16_elf64_howto_table_rela[0])); 2372 i++) 2373 if (mips16_elf64_howto_table_rela[i].name != NULL 2374 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0) 2375 return &mips16_elf64_howto_table_rela[i]; 2376 2377 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0) 2378 return &elf_mips_gnu_vtinherit_howto; 2379 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0) 2380 return &elf_mips_gnu_vtentry_howto; 2381 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0) 2382 return &elf_mips_gnu_rel16_s2; 2383 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0) 2384 return &elf_mips_gnu_rela16_s2; 2385 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0) 2386 return &elf_mips_copy_howto; 2387 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0) 2388 return &elf_mips_jump_slot_howto; 2389 2390 return NULL; 2391 } 2392 2393 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */ 2394 2395 static reloc_howto_type * 2396 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p) 2397 { 2398 switch (r_type) 2399 { 2400 case R_MIPS_GNU_VTINHERIT: 2401 return &elf_mips_gnu_vtinherit_howto; 2402 case R_MIPS_GNU_VTENTRY: 2403 return &elf_mips_gnu_vtentry_howto; 2404 case R_MIPS_GNU_REL16_S2: 2405 if (rela_p) 2406 return &elf_mips_gnu_rela16_s2; 2407 else 2408 return &elf_mips_gnu_rel16_s2; 2409 case R_MIPS_COPY: 2410 return &elf_mips_copy_howto; 2411 case R_MIPS_JUMP_SLOT: 2412 return &elf_mips_jump_slot_howto; 2413 default: 2414 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max) 2415 { 2416 if (rela_p) 2417 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min]; 2418 else 2419 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min]; 2420 } 2421 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max); 2422 if (rela_p) 2423 return &mips_elf64_howto_table_rela[r_type]; 2424 else 2425 return &mips_elf64_howto_table_rel[r_type]; 2426 break; 2427 } 2428 } 2429 2430 /* Prevent relocation handling by bfd for MIPS ELF64. */ 2431 2432 static void 2433 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, 2434 arelent *cache_ptr ATTRIBUTE_UNUSED, 2435 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) 2436 { 2437 BFD_ASSERT (0); 2438 } 2439 2440 static void 2441 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, 2442 arelent *cache_ptr ATTRIBUTE_UNUSED, 2443 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) 2444 { 2445 BFD_ASSERT (0); 2446 } 2447 2448 /* Since each entry in an SHT_REL or SHT_RELA section can represent up 2449 to three relocs, we must tell the user to allocate more space. */ 2450 2451 static long 2452 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) 2453 { 2454 return (sec->reloc_count * 3 + 1) * sizeof (arelent *); 2455 } 2456 2457 static long 2458 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd) 2459 { 2460 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3; 2461 } 2462 2463 /* We must also copy more relocations than the corresponding functions 2464 in elf.c would, so the two following functions are slightly 2465 modified from elf.c, that multiply the external relocation count by 2466 3 to obtain the internal relocation count. */ 2467 2468 static long 2469 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section, 2470 arelent **relptr, asymbol **symbols) 2471 { 2472 arelent *tblptr; 2473 unsigned int i; 2474 const struct elf_backend_data *bed = get_elf_backend_data (abfd); 2475 2476 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE)) 2477 return -1; 2478 2479 tblptr = section->relocation; 2480 for (i = 0; i < section->reloc_count * 3; i++) 2481 *relptr++ = tblptr++; 2482 2483 *relptr = NULL; 2484 2485 return section->reloc_count * 3; 2486 } 2487 2488 static long 2489 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage, 2490 asymbol **syms) 2491 { 2492 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); 2493 asection *s; 2494 long ret; 2495 2496 if (elf_dynsymtab (abfd) == 0) 2497 { 2498 bfd_set_error (bfd_error_invalid_operation); 2499 return -1; 2500 } 2501 2502 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; 2503 ret = 0; 2504 for (s = abfd->sections; s != NULL; s = s->next) 2505 { 2506 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) 2507 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL 2508 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) 2509 { 2510 arelent *p; 2511 long count, i; 2512 2513 if (! (*slurp_relocs) (abfd, s, syms, TRUE)) 2514 return -1; 2515 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3; 2516 p = s->relocation; 2517 for (i = 0; i < count; i++) 2518 *storage++ = p++; 2519 ret += count; 2520 } 2521 } 2522 2523 *storage = NULL; 2524 2525 return ret; 2526 } 2527 2528 /* Read the relocations from one reloc section. This is mostly copied 2529 from elfcode.h, except for the changes to expand one external 2530 relocation to 3 internal ones. We must unfortunately set 2531 reloc_count to the number of external relocations, because a lot of 2532 generic code seems to depend on this. */ 2533 2534 static bfd_boolean 2535 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect, 2536 Elf_Internal_Shdr *rel_hdr, 2537 bfd_size_type reloc_count, 2538 arelent *relents, asymbol **symbols, 2539 bfd_boolean dynamic) 2540 { 2541 void *allocated; 2542 bfd_byte *native_relocs; 2543 arelent *relent; 2544 bfd_vma i; 2545 int entsize; 2546 bfd_boolean rela_p; 2547 2548 allocated = bfd_malloc (rel_hdr->sh_size); 2549 if (allocated == NULL) 2550 return FALSE; 2551 2552 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0 2553 || (bfd_bread (allocated, rel_hdr->sh_size, abfd) 2554 != rel_hdr->sh_size)) 2555 goto error_return; 2556 2557 native_relocs = allocated; 2558 2559 entsize = rel_hdr->sh_entsize; 2560 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel) 2561 || entsize == sizeof (Elf64_Mips_External_Rela)); 2562 2563 if (entsize == sizeof (Elf64_Mips_External_Rel)) 2564 rela_p = FALSE; 2565 else 2566 rela_p = TRUE; 2567 2568 for (i = 0, relent = relents; 2569 i < reloc_count; 2570 i++, native_relocs += entsize) 2571 { 2572 Elf64_Mips_Internal_Rela rela; 2573 bfd_boolean used_sym, used_ssym; 2574 int ir; 2575 2576 if (entsize == sizeof (Elf64_Mips_External_Rela)) 2577 mips_elf64_swap_reloca_in (abfd, 2578 (Elf64_Mips_External_Rela *) native_relocs, 2579 &rela); 2580 else 2581 mips_elf64_swap_reloc_in (abfd, 2582 (Elf64_Mips_External_Rel *) native_relocs, 2583 &rela); 2584 2585 /* Each entry represents exactly three actual relocations. */ 2586 2587 used_sym = FALSE; 2588 used_ssym = FALSE; 2589 for (ir = 0; ir < 3; ir++) 2590 { 2591 enum elf_mips_reloc_type type; 2592 2593 switch (ir) 2594 { 2595 default: 2596 abort (); 2597 case 0: 2598 type = (enum elf_mips_reloc_type) rela.r_type; 2599 break; 2600 case 1: 2601 type = (enum elf_mips_reloc_type) rela.r_type2; 2602 break; 2603 case 2: 2604 type = (enum elf_mips_reloc_type) rela.r_type3; 2605 break; 2606 } 2607 2608 /* Some types require symbols, whereas some do not. */ 2609 switch (type) 2610 { 2611 case R_MIPS_NONE: 2612 case R_MIPS_LITERAL: 2613 case R_MIPS_INSERT_A: 2614 case R_MIPS_INSERT_B: 2615 case R_MIPS_DELETE: 2616 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 2617 break; 2618 2619 default: 2620 if (! used_sym) 2621 { 2622 if (rela.r_sym == STN_UNDEF) 2623 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 2624 else 2625 { 2626 asymbol **ps, *s; 2627 2628 ps = symbols + rela.r_sym - 1; 2629 s = *ps; 2630 if ((s->flags & BSF_SECTION_SYM) == 0) 2631 relent->sym_ptr_ptr = ps; 2632 else 2633 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; 2634 } 2635 2636 used_sym = TRUE; 2637 } 2638 else if (! used_ssym) 2639 { 2640 switch (rela.r_ssym) 2641 { 2642 case RSS_UNDEF: 2643 relent->sym_ptr_ptr = 2644 bfd_abs_section_ptr->symbol_ptr_ptr; 2645 break; 2646 2647 case RSS_GP: 2648 case RSS_GP0: 2649 case RSS_LOC: 2650 /* FIXME: I think these need to be handled using 2651 special howto structures. */ 2652 BFD_ASSERT (0); 2653 break; 2654 2655 default: 2656 BFD_ASSERT (0); 2657 break; 2658 } 2659 2660 used_ssym = TRUE; 2661 } 2662 else 2663 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 2664 2665 break; 2666 } 2667 2668 /* The address of an ELF reloc is section relative for an 2669 object file, and absolute for an executable file or 2670 shared library. The address of a BFD reloc is always 2671 section relative. */ 2672 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic) 2673 relent->address = rela.r_offset; 2674 else 2675 relent->address = rela.r_offset - asect->vma; 2676 2677 relent->addend = rela.r_addend; 2678 2679 relent->howto = mips_elf64_rtype_to_howto (type, rela_p); 2680 2681 ++relent; 2682 } 2683 } 2684 2685 asect->reloc_count += (relent - relents) / 3; 2686 2687 if (allocated != NULL) 2688 free (allocated); 2689 2690 return TRUE; 2691 2692 error_return: 2693 if (allocated != NULL) 2694 free (allocated); 2695 return FALSE; 2696 } 2697 2698 /* Read the relocations. On Irix 6, there can be two reloc sections 2699 associated with a single data section. This is copied from 2700 elfcode.h as well, with changes as small as accounting for 3 2701 internal relocs per external reloc and resetting reloc_count to 2702 zero before processing the relocs of a section. */ 2703 2704 static bfd_boolean 2705 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect, 2706 asymbol **symbols, bfd_boolean dynamic) 2707 { 2708 struct bfd_elf_section_data * const d = elf_section_data (asect); 2709 Elf_Internal_Shdr *rel_hdr; 2710 Elf_Internal_Shdr *rel_hdr2; 2711 bfd_size_type reloc_count; 2712 bfd_size_type reloc_count2; 2713 arelent *relents; 2714 bfd_size_type amt; 2715 2716 if (asect->relocation != NULL) 2717 return TRUE; 2718 2719 if (! dynamic) 2720 { 2721 if ((asect->flags & SEC_RELOC) == 0 2722 || asect->reloc_count == 0) 2723 return TRUE; 2724 2725 rel_hdr = d->rel.hdr; 2726 reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0; 2727 rel_hdr2 = d->rela.hdr; 2728 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0); 2729 2730 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2); 2731 BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset) 2732 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset)); 2733 2734 } 2735 else 2736 { 2737 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this 2738 case because relocations against this section may use the 2739 dynamic symbol table, and in that case bfd_section_from_shdr 2740 in elf.c does not update the RELOC_COUNT. */ 2741 if (asect->size == 0) 2742 return TRUE; 2743 2744 rel_hdr = &d->this_hdr; 2745 reloc_count = NUM_SHDR_ENTRIES (rel_hdr); 2746 rel_hdr2 = NULL; 2747 reloc_count2 = 0; 2748 } 2749 2750 /* Allocate space for 3 arelent structures for each Rel structure. */ 2751 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent); 2752 relents = bfd_alloc (abfd, amt); 2753 if (relents == NULL) 2754 return FALSE; 2755 2756 /* The slurp_one_reloc_table routine increments reloc_count. */ 2757 asect->reloc_count = 0; 2758 2759 if (rel_hdr != NULL 2760 && ! mips_elf64_slurp_one_reloc_table (abfd, asect, 2761 rel_hdr, reloc_count, 2762 relents, 2763 symbols, dynamic)) 2764 return FALSE; 2765 if (rel_hdr2 != NULL 2766 && ! mips_elf64_slurp_one_reloc_table (abfd, asect, 2767 rel_hdr2, reloc_count2, 2768 relents + reloc_count * 3, 2769 symbols, dynamic)) 2770 return FALSE; 2771 2772 asect->relocation = relents; 2773 return TRUE; 2774 } 2775 2776 /* Write out the relocations. */ 2777 2778 static void 2779 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data) 2780 { 2781 bfd_boolean *failedp = data; 2782 int count; 2783 Elf_Internal_Shdr *rel_hdr; 2784 unsigned int idx; 2785 2786 /* If we have already failed, don't do anything. */ 2787 if (*failedp) 2788 return; 2789 2790 if ((sec->flags & SEC_RELOC) == 0) 2791 return; 2792 2793 /* The linker backend writes the relocs out itself, and sets the 2794 reloc_count field to zero to inhibit writing them here. Also, 2795 sometimes the SEC_RELOC flag gets set even when there aren't any 2796 relocs. */ 2797 if (sec->reloc_count == 0) 2798 return; 2799 2800 /* We can combine up to three relocs that refer to the same address 2801 if the latter relocs have no associated symbol. */ 2802 count = 0; 2803 for (idx = 0; idx < sec->reloc_count; idx++) 2804 { 2805 bfd_vma addr; 2806 unsigned int i; 2807 2808 ++count; 2809 2810 addr = sec->orelocation[idx]->address; 2811 for (i = 0; i < 2; i++) 2812 { 2813 arelent *r; 2814 2815 if (idx + 1 >= sec->reloc_count) 2816 break; 2817 r = sec->orelocation[idx + 1]; 2818 if (r->address != addr 2819 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section) 2820 || (*r->sym_ptr_ptr)->value != 0) 2821 break; 2822 2823 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */ 2824 2825 ++idx; 2826 } 2827 } 2828 2829 rel_hdr = _bfd_elf_single_rel_hdr (sec); 2830 2831 /* Do the actual relocation. */ 2832 2833 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel)) 2834 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data); 2835 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela)) 2836 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data); 2837 else 2838 BFD_ASSERT (0); 2839 } 2840 2841 static void 2842 mips_elf64_write_rel (bfd *abfd, asection *sec, 2843 Elf_Internal_Shdr *rel_hdr, 2844 int *count, void *data) 2845 { 2846 bfd_boolean *failedp = data; 2847 Elf64_Mips_External_Rel *ext_rel; 2848 unsigned int idx; 2849 asymbol *last_sym = 0; 2850 int last_sym_idx = 0; 2851 2852 rel_hdr->sh_size = rel_hdr->sh_entsize * *count; 2853 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size); 2854 if (rel_hdr->contents == NULL) 2855 { 2856 *failedp = TRUE; 2857 return; 2858 } 2859 2860 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents; 2861 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++) 2862 { 2863 arelent *ptr; 2864 Elf64_Mips_Internal_Rela int_rel; 2865 asymbol *sym; 2866 int n; 2867 unsigned int i; 2868 2869 ptr = sec->orelocation[idx]; 2870 2871 /* The address of an ELF reloc is section relative for an object 2872 file, and absolute for an executable file or shared library. 2873 The address of a BFD reloc is always section relative. */ 2874 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) 2875 int_rel.r_offset = ptr->address; 2876 else 2877 int_rel.r_offset = ptr->address + sec->vma; 2878 2879 sym = *ptr->sym_ptr_ptr; 2880 if (sym == last_sym) 2881 n = last_sym_idx; 2882 else if (bfd_is_abs_section (sym->section) && sym->value == 0) 2883 n = STN_UNDEF; 2884 else 2885 { 2886 last_sym = sym; 2887 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); 2888 if (n < 0) 2889 { 2890 *failedp = TRUE; 2891 return; 2892 } 2893 last_sym_idx = n; 2894 } 2895 2896 int_rel.r_sym = n; 2897 int_rel.r_ssym = RSS_UNDEF; 2898 2899 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec 2900 && ! _bfd_elf_validate_reloc (abfd, ptr)) 2901 { 2902 *failedp = TRUE; 2903 return; 2904 } 2905 2906 int_rel.r_type = ptr->howto->type; 2907 int_rel.r_type2 = (int) R_MIPS_NONE; 2908 int_rel.r_type3 = (int) R_MIPS_NONE; 2909 2910 for (i = 0; i < 2; i++) 2911 { 2912 arelent *r; 2913 2914 if (idx + 1 >= sec->reloc_count) 2915 break; 2916 r = sec->orelocation[idx + 1]; 2917 if (r->address != ptr->address 2918 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section) 2919 || (*r->sym_ptr_ptr)->value != 0) 2920 break; 2921 2922 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */ 2923 2924 if (i == 0) 2925 int_rel.r_type2 = r->howto->type; 2926 else 2927 int_rel.r_type3 = r->howto->type; 2928 2929 ++idx; 2930 } 2931 2932 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel); 2933 } 2934 2935 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents 2936 == *count); 2937 } 2938 2939 static void 2940 mips_elf64_write_rela (bfd *abfd, asection *sec, 2941 Elf_Internal_Shdr *rela_hdr, 2942 int *count, void *data) 2943 { 2944 bfd_boolean *failedp = data; 2945 Elf64_Mips_External_Rela *ext_rela; 2946 unsigned int idx; 2947 asymbol *last_sym = 0; 2948 int last_sym_idx = 0; 2949 2950 rela_hdr->sh_size = rela_hdr->sh_entsize * *count; 2951 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size); 2952 if (rela_hdr->contents == NULL) 2953 { 2954 *failedp = TRUE; 2955 return; 2956 } 2957 2958 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents; 2959 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++) 2960 { 2961 arelent *ptr; 2962 Elf64_Mips_Internal_Rela int_rela; 2963 asymbol *sym; 2964 int n; 2965 unsigned int i; 2966 2967 ptr = sec->orelocation[idx]; 2968 2969 /* The address of an ELF reloc is section relative for an object 2970 file, and absolute for an executable file or shared library. 2971 The address of a BFD reloc is always section relative. */ 2972 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) 2973 int_rela.r_offset = ptr->address; 2974 else 2975 int_rela.r_offset = ptr->address + sec->vma; 2976 2977 sym = *ptr->sym_ptr_ptr; 2978 if (sym == last_sym) 2979 n = last_sym_idx; 2980 else if (bfd_is_abs_section (sym->section) && sym->value == 0) 2981 n = STN_UNDEF; 2982 else 2983 { 2984 last_sym = sym; 2985 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); 2986 if (n < 0) 2987 { 2988 *failedp = TRUE; 2989 return; 2990 } 2991 last_sym_idx = n; 2992 } 2993 2994 int_rela.r_sym = n; 2995 int_rela.r_addend = ptr->addend; 2996 int_rela.r_ssym = RSS_UNDEF; 2997 2998 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec 2999 && ! _bfd_elf_validate_reloc (abfd, ptr)) 3000 { 3001 *failedp = TRUE; 3002 return; 3003 } 3004 3005 int_rela.r_type = ptr->howto->type; 3006 int_rela.r_type2 = (int) R_MIPS_NONE; 3007 int_rela.r_type3 = (int) R_MIPS_NONE; 3008 3009 for (i = 0; i < 2; i++) 3010 { 3011 arelent *r; 3012 3013 if (idx + 1 >= sec->reloc_count) 3014 break; 3015 r = sec->orelocation[idx + 1]; 3016 if (r->address != ptr->address 3017 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section) 3018 || (*r->sym_ptr_ptr)->value != 0) 3019 break; 3020 3021 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */ 3022 3023 if (i == 0) 3024 int_rela.r_type2 = r->howto->type; 3025 else 3026 int_rela.r_type3 = r->howto->type; 3027 3028 ++idx; 3029 } 3030 3031 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela); 3032 } 3033 3034 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents 3035 == *count); 3036 } 3037 3038 /* Set the right machine number for a MIPS ELF file. */ 3039 3040 static bfd_boolean 3041 mips_elf64_object_p (bfd *abfd) 3042 { 3043 unsigned long mach; 3044 3045 /* Irix 6 is broken. Object file symbol tables are not always 3046 sorted correctly such that local symbols precede global symbols, 3047 and the sh_info field in the symbol table is not always right. */ 3048 if (elf64_mips_irix_compat (abfd) != ict_none) 3049 elf_bad_symtab (abfd) = TRUE; 3050 3051 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags); 3052 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach); 3053 return TRUE; 3054 } 3055 3056 /* Depending on the target vector we generate some version of Irix 3057 executables or "normal" MIPS ELF ABI executables. */ 3058 static irix_compat_t 3059 elf64_mips_irix_compat (bfd *abfd) 3060 { 3061 if ((abfd->xvec == &bfd_elf64_bigmips_vec) 3062 || (abfd->xvec == &bfd_elf64_littlemips_vec)) 3063 return ict_irix6; 3064 else 3065 return ict_none; 3066 } 3067 3068 /* Support for core dump NOTE sections. */ 3069 static bfd_boolean 3070 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 3071 { 3072 int offset; 3073 unsigned int size; 3074 3075 switch (note->descsz) 3076 { 3077 default: 3078 return FALSE; 3079 3080 case 480: /* Linux/MIPS - N64 kernel */ 3081 /* pr_cursig */ 3082 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); 3083 3084 /* pr_pid */ 3085 elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 32); 3086 3087 /* pr_reg */ 3088 offset = 112; 3089 size = 360; 3090 3091 break; 3092 } 3093 3094 /* Make a ".reg/999" section. */ 3095 return _bfd_elfcore_make_pseudosection (abfd, ".reg", 3096 size, note->descpos + offset); 3097 } 3098 3099 static bfd_boolean 3100 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 3101 { 3102 switch (note->descsz) 3103 { 3104 default: 3105 return FALSE; 3106 3107 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */ 3108 elf_tdata (abfd)->core_program 3109 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16); 3110 elf_tdata (abfd)->core_command 3111 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80); 3112 } 3113 3114 /* Note that for some reason, a spurious space is tacked 3115 onto the end of the args in some (at least one anyway) 3116 implementations, so strip it off if it exists. */ 3117 3118 { 3119 char *command = elf_tdata (abfd)->core_command; 3120 int n = strlen (command); 3121 3122 if (0 < n && command[n - 1] == ' ') 3123 command[n - 1] = '\0'; 3124 } 3125 3126 return TRUE; 3127 } 3128 3129 /* ECOFF swapping routines. These are used when dealing with the 3130 .mdebug section, which is in the ECOFF debugging format. */ 3131 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap = 3132 { 3133 /* Symbol table magic number. */ 3134 magicSym2, 3135 /* Alignment of debugging information. E.g., 4. */ 3136 8, 3137 /* Sizes of external symbolic information. */ 3138 sizeof (struct hdr_ext), 3139 sizeof (struct dnr_ext), 3140 sizeof (struct pdr_ext), 3141 sizeof (struct sym_ext), 3142 sizeof (struct opt_ext), 3143 sizeof (struct fdr_ext), 3144 sizeof (struct rfd_ext), 3145 sizeof (struct ext_ext), 3146 /* Functions to swap in external symbolic data. */ 3147 ecoff_swap_hdr_in, 3148 ecoff_swap_dnr_in, 3149 ecoff_swap_pdr_in, 3150 ecoff_swap_sym_in, 3151 ecoff_swap_opt_in, 3152 ecoff_swap_fdr_in, 3153 ecoff_swap_rfd_in, 3154 ecoff_swap_ext_in, 3155 _bfd_ecoff_swap_tir_in, 3156 _bfd_ecoff_swap_rndx_in, 3157 /* Functions to swap out external symbolic data. */ 3158 ecoff_swap_hdr_out, 3159 ecoff_swap_dnr_out, 3160 ecoff_swap_pdr_out, 3161 ecoff_swap_sym_out, 3162 ecoff_swap_opt_out, 3163 ecoff_swap_fdr_out, 3164 ecoff_swap_rfd_out, 3165 ecoff_swap_ext_out, 3166 _bfd_ecoff_swap_tir_out, 3167 _bfd_ecoff_swap_rndx_out, 3168 /* Function to read in symbolic data. */ 3169 _bfd_mips_elf_read_ecoff_info 3170 }; 3171 3172 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in 3173 standard ELF. This structure is used to redirect the relocation 3174 handling routines. */ 3175 3176 const struct elf_size_info mips_elf64_size_info = 3177 { 3178 sizeof (Elf64_External_Ehdr), 3179 sizeof (Elf64_External_Phdr), 3180 sizeof (Elf64_External_Shdr), 3181 sizeof (Elf64_Mips_External_Rel), 3182 sizeof (Elf64_Mips_External_Rela), 3183 sizeof (Elf64_External_Sym), 3184 sizeof (Elf64_External_Dyn), 3185 sizeof (Elf_External_Note), 3186 4, /* hash-table entry size */ 3187 3, /* internal relocations per external relocations */ 3188 64, /* arch_size */ 3189 3, /* log_file_align */ 3190 ELFCLASS64, 3191 EV_CURRENT, 3192 bfd_elf64_write_out_phdrs, 3193 bfd_elf64_write_shdrs_and_ehdr, 3194 bfd_elf64_checksum_contents, 3195 mips_elf64_write_relocs, 3196 bfd_elf64_swap_symbol_in, 3197 bfd_elf64_swap_symbol_out, 3198 mips_elf64_slurp_reloc_table, 3199 bfd_elf64_slurp_symbol_table, 3200 bfd_elf64_swap_dyn_in, 3201 bfd_elf64_swap_dyn_out, 3202 mips_elf64_be_swap_reloc_in, 3203 mips_elf64_be_swap_reloc_out, 3204 mips_elf64_be_swap_reloca_in, 3205 mips_elf64_be_swap_reloca_out 3206 }; 3207 3208 #define ELF_ARCH bfd_arch_mips 3209 #define ELF_TARGET_ID MIPS_ELF_DATA 3210 #define ELF_MACHINE_CODE EM_MIPS 3211 3212 #define elf_backend_collect TRUE 3213 #define elf_backend_type_change_ok TRUE 3214 #define elf_backend_can_gc_sections TRUE 3215 #define elf_info_to_howto mips_elf64_info_to_howto_rela 3216 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel 3217 #define elf_backend_object_p mips_elf64_object_p 3218 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing 3219 #define elf_backend_section_processing _bfd_mips_elf_section_processing 3220 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr 3221 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections 3222 #define elf_backend_section_from_bfd_section \ 3223 _bfd_mips_elf_section_from_bfd_section 3224 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook 3225 #define elf_backend_link_output_symbol_hook \ 3226 _bfd_mips_elf_link_output_symbol_hook 3227 #define elf_backend_create_dynamic_sections \ 3228 _bfd_mips_elf_create_dynamic_sections 3229 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs 3230 #define elf_backend_merge_symbol_attribute \ 3231 _bfd_mips_elf_merge_symbol_attribute 3232 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag 3233 #define elf_backend_adjust_dynamic_symbol \ 3234 _bfd_mips_elf_adjust_dynamic_symbol 3235 #define elf_backend_always_size_sections \ 3236 _bfd_mips_elf_always_size_sections 3237 #define elf_backend_size_dynamic_sections \ 3238 _bfd_mips_elf_size_dynamic_sections 3239 #define elf_backend_init_index_section _bfd_elf_init_1_index_section 3240 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section 3241 #define elf_backend_finish_dynamic_symbol \ 3242 _bfd_mips_elf_finish_dynamic_symbol 3243 #define elf_backend_finish_dynamic_sections \ 3244 _bfd_mips_elf_finish_dynamic_sections 3245 #define elf_backend_final_write_processing \ 3246 _bfd_mips_elf_final_write_processing 3247 #define elf_backend_additional_program_headers \ 3248 _bfd_mips_elf_additional_program_headers 3249 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map 3250 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook 3251 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook 3252 #define elf_backend_copy_indirect_symbol \ 3253 _bfd_mips_elf_copy_indirect_symbol 3254 #define elf_backend_ignore_discarded_relocs \ 3255 _bfd_mips_elf_ignore_discarded_relocs 3256 #define elf_backend_mips_irix_compat elf64_mips_irix_compat 3257 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto 3258 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap 3259 #define elf_backend_size_info mips_elf64_size_info 3260 3261 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus 3262 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo 3263 3264 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO) 3265 3266 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations 3267 work better/work only in RELA, so we default to this. */ 3268 #define elf_backend_may_use_rel_p 1 3269 #define elf_backend_may_use_rela_p 1 3270 #define elf_backend_default_use_rela_p 1 3271 #define elf_backend_rela_plts_and_copies_p 0 3272 #define elf_backend_plt_readonly 1 3273 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val 3274 3275 #define elf_backend_sign_extend_vma TRUE 3276 3277 #define elf_backend_write_section _bfd_mips_elf_write_section 3278 3279 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit 3280 MIPS-specific function only applies to IRIX5, which had no 64-bit 3281 ABI. */ 3282 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line 3283 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info 3284 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook 3285 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents 3286 #define bfd_elf64_bfd_get_relocated_section_contents \ 3287 _bfd_elf_mips_get_relocated_section_contents 3288 #define bfd_elf64_bfd_link_hash_table_create \ 3289 _bfd_mips_elf_link_hash_table_create 3290 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link 3291 #define bfd_elf64_bfd_merge_private_bfd_data \ 3292 _bfd_mips_elf_merge_private_bfd_data 3293 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags 3294 #define bfd_elf64_bfd_print_private_bfd_data \ 3295 _bfd_mips_elf_print_private_bfd_data 3296 3297 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound 3298 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc 3299 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound 3300 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc 3301 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section 3302 3303 /* MIPS ELF64 archive functions. */ 3304 #define bfd_elf64_archive_functions 3305 extern bfd_boolean bfd_elf64_archive_slurp_armap 3306 (bfd *); 3307 extern bfd_boolean bfd_elf64_archive_write_armap 3308 (bfd *, unsigned int, struct orl *, unsigned int, int); 3309 #define bfd_elf64_archive_slurp_extended_name_table \ 3310 _bfd_archive_coff_slurp_extended_name_table 3311 #define bfd_elf64_archive_construct_extended_name_table \ 3312 _bfd_archive_coff_construct_extended_name_table 3313 #define bfd_elf64_archive_truncate_arname \ 3314 _bfd_archive_coff_truncate_arname 3315 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr 3316 #define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_ar_hdr 3317 #define bfd_elf64_archive_openr_next_archived_file \ 3318 _bfd_archive_coff_openr_next_archived_file 3319 #define bfd_elf64_archive_get_elt_at_index \ 3320 _bfd_archive_coff_get_elt_at_index 3321 #define bfd_elf64_archive_generic_stat_arch_elt \ 3322 _bfd_archive_coff_generic_stat_arch_elt 3323 #define bfd_elf64_archive_update_armap_timestamp \ 3324 _bfd_archive_coff_update_armap_timestamp 3325 3326 /* The SGI style (n)64 NewABI. */ 3327 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec 3328 #define TARGET_LITTLE_NAME "elf64-littlemips" 3329 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec 3330 #define TARGET_BIG_NAME "elf64-bigmips" 3331 3332 #define ELF_MAXPAGESIZE 0x10000 3333 #define ELF_COMMONPAGESIZE 0x1000 3334 3335 #include "elf64-target.h" 3336 3337 /* The SYSV-style 'traditional' (n)64 NewABI. */ 3338 #undef TARGET_LITTLE_SYM 3339 #undef TARGET_LITTLE_NAME 3340 #undef TARGET_BIG_SYM 3341 #undef TARGET_BIG_NAME 3342 3343 #undef ELF_MAXPAGESIZE 3344 #undef ELF_COMMONPAGESIZE 3345 3346 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec 3347 #define TARGET_LITTLE_NAME "elf64-tradlittlemips" 3348 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec 3349 #define TARGET_BIG_NAME "elf64-tradbigmips" 3350 3351 #define ELF_MAXPAGESIZE 0x10000 3352 #define ELF_COMMONPAGESIZE 0x1000 3353 #define elf64_bed elf64_tradbed 3354 3355 /* Include the target file again for this target. */ 3356 #include "elf64-target.h" 3357 3358 3359 /* FreeBSD support. */ 3360 3361 #undef TARGET_LITTLE_SYM 3362 #undef TARGET_LITTLE_NAME 3363 #undef TARGET_BIG_SYM 3364 #undef TARGET_BIG_NAME 3365 3366 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_freebsd_vec 3367 #define TARGET_LITTLE_NAME "elf64-tradlittlemips-freebsd" 3368 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_freebsd_vec 3369 #define TARGET_BIG_NAME "elf64-tradbigmips-freebsd" 3370 3371 #undef ELF_OSABI 3372 #define ELF_OSABI ELFOSABI_FREEBSD 3373 3374 /* The kernel recognizes executables as valid only if they carry a 3375 "FreeBSD" label in the ELF header. So we put this label on all 3376 executables and (for simplicity) also all other object files. */ 3377 3378 static void 3379 elf_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) 3380 { 3381 _bfd_elf_set_osabi (abfd, info); 3382 } 3383 3384 #undef elf_backend_post_process_headers 3385 #define elf_backend_post_process_headers elf_fbsd_post_process_headers 3386 #undef elf64_bed 3387 #define elf64_bed elf64_fbsd_tradbed 3388 3389 #include "elf64-target.h" 3390