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