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