1 /* MIPS-specific support for 64-bit ELF 2 Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc. 3 Ian Lance Taylor, Cygnus Support 4 Linker support added by Mark Mitchell, CodeSourcery, LLC. 5 <mark@codesourcery.com> 6 7 This file is part of BFD, the Binary File Descriptor library. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 22 23 /* This file supports the 64-bit MIPS ELF ABI. 24 25 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file 26 overrides the usual ELF reloc handling, and handles reading and 27 writing the relocations here. 28 29 The MIPS 64-bit ELF ABI also uses an unusual archive map format. */ 30 31 #include "bfd.h" 32 #include "sysdep.h" 33 #include "libbfd.h" 34 #include "aout/ar.h" 35 #include "bfdlink.h" 36 #include "genlink.h" 37 #include "elf-bfd.h" 38 #include "elf/mips.h" 39 40 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to 41 use ECOFF. However, we support it anyhow for an easier changeover. */ 42 #include "coff/sym.h" 43 #include "coff/symconst.h" 44 #include "coff/internal.h" 45 #include "coff/ecoff.h" 46 /* The 64 bit versions of the mdebug data structures are in alpha.h. */ 47 #include "coff/alpha.h" 48 #define ECOFF_64 49 #include "ecoffswap.h" 50 51 static void mips_elf64_swap_reloc_in 52 PARAMS ((bfd *, const Elf64_Mips_External_Rel *, 53 Elf64_Mips_Internal_Rel *)); 54 static void mips_elf64_swap_reloca_in 55 PARAMS ((bfd *, const Elf64_Mips_External_Rela *, 56 Elf64_Mips_Internal_Rela *)); 57 static void mips_elf64_swap_reloc_out 58 PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *, 59 Elf64_Mips_External_Rel *)); 60 static void mips_elf64_swap_reloca_out 61 PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *, 62 Elf64_Mips_External_Rela *)); 63 static void mips_elf64_be_swap_reloc_in 64 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *)); 65 static void mips_elf64_be_swap_reloc_out 66 PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *)); 67 static void mips_elf64_be_swap_reloca_in 68 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); 69 static void mips_elf64_be_swap_reloca_out 70 PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); 71 static reloc_howto_type *mips_elf64_reloc_type_lookup 72 PARAMS ((bfd *, bfd_reloc_code_real_type)); 73 static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *)); 74 static boolean mips_elf64_slurp_one_reloc_table 75 PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *)); 76 static boolean mips_elf64_slurp_reloc_table 77 PARAMS ((bfd *, asection *, asymbol **, boolean)); 78 static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR)); 79 static boolean mips_elf64_slurp_armap PARAMS ((bfd *)); 80 static boolean mips_elf64_write_armap 81 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); 82 83 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value 84 from smaller values. Start with zero, widen, *then* decrement. */ 85 #define MINUS_ONE (((bfd_vma)0) - 1) 86 87 /* The number of local .got entries we reserve. */ 88 #define MIPS_RESERVED_GOTNO (2) 89 90 /* The relocation table used for SHT_REL sections. */ 91 92 static reloc_howto_type mips_elf64_howto_table_rel[] = 93 { 94 /* No relocation. */ 95 HOWTO (R_MIPS_NONE, /* type */ 96 0, /* rightshift */ 97 0, /* size (0 = byte, 1 = short, 2 = long) */ 98 0, /* bitsize */ 99 false, /* pc_relative */ 100 0, /* bitpos */ 101 complain_overflow_dont, /* complain_on_overflow */ 102 bfd_elf_generic_reloc, /* special_function */ 103 "R_MIPS_NONE", /* name */ 104 false, /* partial_inplace */ 105 0, /* src_mask */ 106 0, /* dst_mask */ 107 false), /* pcrel_offset */ 108 109 /* 16 bit relocation. */ 110 HOWTO (R_MIPS_16, /* type */ 111 0, /* rightshift */ 112 1, /* size (0 = byte, 1 = short, 2 = long) */ 113 16, /* bitsize */ 114 false, /* pc_relative */ 115 0, /* bitpos */ 116 complain_overflow_bitfield, /* complain_on_overflow */ 117 bfd_elf_generic_reloc, /* special_function */ 118 "R_MIPS_16", /* name */ 119 true, /* partial_inplace */ 120 0xffff, /* src_mask */ 121 0xffff, /* dst_mask */ 122 false), /* pcrel_offset */ 123 124 /* 32 bit relocation. */ 125 HOWTO (R_MIPS_32, /* type */ 126 0, /* rightshift */ 127 2, /* size (0 = byte, 1 = short, 2 = long) */ 128 32, /* bitsize */ 129 false, /* pc_relative */ 130 0, /* bitpos */ 131 complain_overflow_bitfield, /* complain_on_overflow */ 132 bfd_elf_generic_reloc, /* special_function */ 133 "R_MIPS_32", /* name */ 134 true, /* partial_inplace */ 135 0xffffffff, /* src_mask */ 136 0xffffffff, /* dst_mask */ 137 false), /* pcrel_offset */ 138 139 /* 32 bit symbol relative relocation. */ 140 HOWTO (R_MIPS_REL32, /* type */ 141 0, /* rightshift */ 142 2, /* size (0 = byte, 1 = short, 2 = long) */ 143 32, /* bitsize */ 144 false, /* pc_relative */ 145 0, /* bitpos */ 146 complain_overflow_bitfield, /* complain_on_overflow */ 147 bfd_elf_generic_reloc, /* special_function */ 148 "R_MIPS_REL32", /* name */ 149 true, /* partial_inplace */ 150 0xffffffff, /* src_mask */ 151 0xffffffff, /* dst_mask */ 152 false), /* pcrel_offset */ 153 154 /* 26 bit branch address. */ 155 HOWTO (R_MIPS_26, /* type */ 156 2, /* rightshift */ 157 2, /* size (0 = byte, 1 = short, 2 = long) */ 158 26, /* bitsize */ 159 false, /* pc_relative */ 160 0, /* bitpos */ 161 complain_overflow_dont, /* complain_on_overflow */ 162 /* This needs complex overflow 163 detection, because the upper four 164 bits must match the PC. */ 165 bfd_elf_generic_reloc, /* special_function */ 166 "R_MIPS_26", /* name */ 167 true, /* partial_inplace */ 168 0x3ffffff, /* src_mask */ 169 0x3ffffff, /* dst_mask */ 170 false), /* pcrel_offset */ 171 172 /* High 16 bits of symbol value. */ 173 HOWTO (R_MIPS_HI16, /* type */ 174 0, /* rightshift */ 175 2, /* size (0 = byte, 1 = short, 2 = long) */ 176 16, /* bitsize */ 177 false, /* pc_relative */ 178 0, /* bitpos */ 179 complain_overflow_dont, /* complain_on_overflow */ 180 _bfd_mips_elf_hi16_reloc, /* special_function */ 181 "R_MIPS_HI16", /* name */ 182 true, /* partial_inplace */ 183 0xffff, /* src_mask */ 184 0xffff, /* dst_mask */ 185 false), /* pcrel_offset */ 186 187 /* Low 16 bits of symbol value. */ 188 HOWTO (R_MIPS_LO16, /* type */ 189 0, /* rightshift */ 190 2, /* size (0 = byte, 1 = short, 2 = long) */ 191 16, /* bitsize */ 192 false, /* pc_relative */ 193 0, /* bitpos */ 194 complain_overflow_dont, /* complain_on_overflow */ 195 _bfd_mips_elf_lo16_reloc, /* special_function */ 196 "R_MIPS_LO16", /* name */ 197 true, /* partial_inplace */ 198 0xffff, /* src_mask */ 199 0xffff, /* dst_mask */ 200 false), /* pcrel_offset */ 201 202 /* GP relative reference. */ 203 HOWTO (R_MIPS_GPREL16, /* type */ 204 0, /* rightshift */ 205 2, /* size (0 = byte, 1 = short, 2 = long) */ 206 16, /* bitsize */ 207 false, /* pc_relative */ 208 0, /* bitpos */ 209 complain_overflow_signed, /* complain_on_overflow */ 210 _bfd_mips_elf_gprel16_reloc, /* special_function */ 211 "R_MIPS_GPREL16", /* name */ 212 true, /* partial_inplace */ 213 0xffff, /* src_mask */ 214 0xffff, /* dst_mask */ 215 false), /* pcrel_offset */ 216 217 /* Reference to literal section. */ 218 HOWTO (R_MIPS_LITERAL, /* type */ 219 0, /* rightshift */ 220 2, /* size (0 = byte, 1 = short, 2 = long) */ 221 16, /* bitsize */ 222 false, /* pc_relative */ 223 0, /* bitpos */ 224 complain_overflow_signed, /* complain_on_overflow */ 225 _bfd_mips_elf_gprel16_reloc, /* special_function */ 226 "R_MIPS_LITERAL", /* name */ 227 true, /* partial_inplace */ 228 0xffff, /* src_mask */ 229 0xffff, /* dst_mask */ 230 false), /* pcrel_offset */ 231 232 /* Reference to global offset table. */ 233 HOWTO (R_MIPS_GOT16, /* type */ 234 0, /* rightshift */ 235 2, /* size (0 = byte, 1 = short, 2 = long) */ 236 16, /* bitsize */ 237 false, /* pc_relative */ 238 0, /* bitpos */ 239 complain_overflow_signed, /* complain_on_overflow */ 240 _bfd_mips_elf_got16_reloc, /* special_function */ 241 "R_MIPS_GOT16", /* name */ 242 false, /* partial_inplace */ 243 0, /* src_mask */ 244 0xffff, /* dst_mask */ 245 false), /* pcrel_offset */ 246 247 /* 16 bit PC relative reference. */ 248 HOWTO (R_MIPS_PC16, /* type */ 249 0, /* rightshift */ 250 2, /* size (0 = byte, 1 = short, 2 = long) */ 251 16, /* bitsize */ 252 true, /* pc_relative */ 253 0, /* bitpos */ 254 complain_overflow_signed, /* complain_on_overflow */ 255 bfd_elf_generic_reloc, /* special_function */ 256 "R_MIPS_PC16", /* name */ 257 true, /* partial_inplace */ 258 0xffff, /* src_mask */ 259 0xffff, /* dst_mask */ 260 false), /* pcrel_offset */ 261 262 /* 16 bit call through global offset table. */ 263 /* FIXME: This is not handled correctly. */ 264 HOWTO (R_MIPS_CALL16, /* type */ 265 0, /* rightshift */ 266 2, /* size (0 = byte, 1 = short, 2 = long) */ 267 16, /* bitsize */ 268 false, /* pc_relative */ 269 0, /* bitpos */ 270 complain_overflow_signed, /* complain_on_overflow */ 271 bfd_elf_generic_reloc, /* special_function */ 272 "R_MIPS_CALL16", /* name */ 273 false, /* partial_inplace */ 274 0, /* src_mask */ 275 0xffff, /* dst_mask */ 276 false), /* pcrel_offset */ 277 278 /* 32 bit GP relative reference. */ 279 HOWTO (R_MIPS_GPREL32, /* type */ 280 0, /* rightshift */ 281 2, /* size (0 = byte, 1 = short, 2 = long) */ 282 32, /* bitsize */ 283 false, /* pc_relative */ 284 0, /* bitpos */ 285 complain_overflow_bitfield, /* complain_on_overflow */ 286 _bfd_mips_elf_gprel32_reloc, /* special_function */ 287 "R_MIPS_GPREL32", /* name */ 288 true, /* partial_inplace */ 289 0xffffffff, /* src_mask */ 290 0xffffffff, /* dst_mask */ 291 false), /* pcrel_offset */ 292 293 { 13 }, 294 { 14 }, 295 { 15 }, 296 297 /* A 5 bit shift field. */ 298 HOWTO (R_MIPS_SHIFT5, /* type */ 299 0, /* rightshift */ 300 2, /* size (0 = byte, 1 = short, 2 = long) */ 301 5, /* bitsize */ 302 false, /* pc_relative */ 303 6, /* bitpos */ 304 complain_overflow_bitfield, /* complain_on_overflow */ 305 bfd_elf_generic_reloc, /* special_function */ 306 "R_MIPS_SHIFT5", /* name */ 307 true, /* partial_inplace */ 308 0x000007c0, /* src_mask */ 309 0x000007c0, /* dst_mask */ 310 false), /* pcrel_offset */ 311 312 /* A 6 bit shift field. */ 313 /* FIXME: This is not handled correctly; a special function is 314 needed to put the most significant bit in the right place. */ 315 HOWTO (R_MIPS_SHIFT6, /* type */ 316 0, /* rightshift */ 317 2, /* size (0 = byte, 1 = short, 2 = long) */ 318 6, /* bitsize */ 319 false, /* pc_relative */ 320 6, /* bitpos */ 321 complain_overflow_bitfield, /* complain_on_overflow */ 322 bfd_elf_generic_reloc, /* special_function */ 323 "R_MIPS_SHIFT6", /* name */ 324 true, /* partial_inplace */ 325 0x000007c4, /* src_mask */ 326 0x000007c4, /* dst_mask */ 327 false), /* pcrel_offset */ 328 329 /* 64 bit relocation. */ 330 HOWTO (R_MIPS_64, /* type */ 331 0, /* rightshift */ 332 4, /* size (0 = byte, 1 = short, 2 = long) */ 333 64, /* bitsize */ 334 false, /* pc_relative */ 335 0, /* bitpos */ 336 complain_overflow_bitfield, /* complain_on_overflow */ 337 bfd_elf_generic_reloc, /* special_function */ 338 "R_MIPS_64", /* name */ 339 true, /* partial_inplace */ 340 MINUS_ONE, /* src_mask */ 341 MINUS_ONE, /* dst_mask */ 342 false), /* pcrel_offset */ 343 344 /* Displacement in the global offset table. */ 345 /* FIXME: Not handled correctly. */ 346 HOWTO (R_MIPS_GOT_DISP, /* type */ 347 0, /* rightshift */ 348 2, /* size (0 = byte, 1 = short, 2 = long) */ 349 16, /* bitsize */ 350 false, /* pc_relative */ 351 0, /* bitpos */ 352 complain_overflow_bitfield, /* complain_on_overflow */ 353 bfd_elf_generic_reloc, /* special_function */ 354 "R_MIPS_GOT_DISP", /* name */ 355 true, /* partial_inplace */ 356 0x0000ffff, /* src_mask */ 357 0x0000ffff, /* dst_mask */ 358 false), /* pcrel_offset */ 359 360 /* Displacement to page pointer in the global offset table. */ 361 /* FIXME: Not handled correctly. */ 362 HOWTO (R_MIPS_GOT_PAGE, /* type */ 363 0, /* rightshift */ 364 2, /* size (0 = byte, 1 = short, 2 = long) */ 365 16, /* bitsize */ 366 false, /* pc_relative */ 367 0, /* bitpos */ 368 complain_overflow_bitfield, /* complain_on_overflow */ 369 bfd_elf_generic_reloc, /* special_function */ 370 "R_MIPS_GOT_PAGE", /* name */ 371 true, /* partial_inplace */ 372 0x0000ffff, /* src_mask */ 373 0x0000ffff, /* dst_mask */ 374 false), /* pcrel_offset */ 375 376 /* Offset from page pointer in the global offset table. */ 377 /* FIXME: Not handled correctly. */ 378 HOWTO (R_MIPS_GOT_OFST, /* type */ 379 0, /* rightshift */ 380 2, /* size (0 = byte, 1 = short, 2 = long) */ 381 16, /* bitsize */ 382 false, /* pc_relative */ 383 0, /* bitpos */ 384 complain_overflow_bitfield, /* complain_on_overflow */ 385 bfd_elf_generic_reloc, /* special_function */ 386 "R_MIPS_GOT_OFST", /* name */ 387 true, /* partial_inplace */ 388 0x0000ffff, /* src_mask */ 389 0x0000ffff, /* dst_mask */ 390 false), /* pcrel_offset */ 391 392 /* High 16 bits of displacement in global offset table. */ 393 /* FIXME: Not handled correctly. */ 394 HOWTO (R_MIPS_GOT_HI16, /* type */ 395 0, /* rightshift */ 396 2, /* size (0 = byte, 1 = short, 2 = long) */ 397 16, /* bitsize */ 398 false, /* pc_relative */ 399 0, /* bitpos */ 400 complain_overflow_dont, /* complain_on_overflow */ 401 bfd_elf_generic_reloc, /* special_function */ 402 "R_MIPS_GOT_HI16", /* name */ 403 true, /* partial_inplace */ 404 0x0000ffff, /* src_mask */ 405 0x0000ffff, /* dst_mask */ 406 false), /* pcrel_offset */ 407 408 /* Low 16 bits of displacement in global offset table. */ 409 /* FIXME: Not handled correctly. */ 410 HOWTO (R_MIPS_GOT_LO16, /* type */ 411 0, /* rightshift */ 412 2, /* size (0 = byte, 1 = short, 2 = long) */ 413 16, /* bitsize */ 414 false, /* pc_relative */ 415 0, /* bitpos */ 416 complain_overflow_dont, /* complain_on_overflow */ 417 bfd_elf_generic_reloc, /* special_function */ 418 "R_MIPS_GOT_LO16", /* name */ 419 true, /* partial_inplace */ 420 0x0000ffff, /* src_mask */ 421 0x0000ffff, /* dst_mask */ 422 false), /* pcrel_offset */ 423 424 /* 64 bit substraction. */ 425 /* FIXME: Not handled correctly. */ 426 HOWTO (R_MIPS_SUB, /* type */ 427 0, /* rightshift */ 428 4, /* size (0 = byte, 1 = short, 2 = long) */ 429 64, /* bitsize */ 430 false, /* pc_relative */ 431 0, /* bitpos */ 432 complain_overflow_bitfield, /* complain_on_overflow */ 433 bfd_elf_generic_reloc, /* special_function */ 434 "R_MIPS_SUB", /* name */ 435 true, /* partial_inplace */ 436 MINUS_ONE, /* src_mask */ 437 MINUS_ONE, /* dst_mask */ 438 false), /* pcrel_offset */ 439 440 /* Insert the addend as an instruction. */ 441 /* FIXME: Not handled correctly. */ 442 HOWTO (R_MIPS_INSERT_A, /* type */ 443 0, /* rightshift */ 444 0, /* size (0 = byte, 1 = short, 2 = long) */ 445 0, /* bitsize */ 446 false, /* pc_relative */ 447 0, /* bitpos */ 448 complain_overflow_dont, /* complain_on_overflow */ 449 bfd_elf_generic_reloc, /* special_function */ 450 "R_MIPS_INSERT_A", /* name */ 451 false, /* partial_inplace */ 452 0, /* src_mask */ 453 0, /* dst_mask */ 454 false), /* pcrel_offset */ 455 456 /* Insert the addend as an instruction, and change all relocations 457 to refer to the old instruction at the address. */ 458 /* FIXME: Not handled correctly. */ 459 HOWTO (R_MIPS_INSERT_B, /* type */ 460 0, /* rightshift */ 461 0, /* size (0 = byte, 1 = short, 2 = long) */ 462 0, /* bitsize */ 463 false, /* pc_relative */ 464 0, /* bitpos */ 465 complain_overflow_dont, /* complain_on_overflow */ 466 bfd_elf_generic_reloc, /* special_function */ 467 "R_MIPS_INSERT_B", /* name */ 468 false, /* partial_inplace */ 469 0, /* src_mask */ 470 0, /* dst_mask */ 471 false), /* pcrel_offset */ 472 473 /* Delete a 32 bit instruction. */ 474 /* FIXME: Not handled correctly. */ 475 HOWTO (R_MIPS_DELETE, /* type */ 476 0, /* rightshift */ 477 0, /* size (0 = byte, 1 = short, 2 = long) */ 478 0, /* bitsize */ 479 false, /* pc_relative */ 480 0, /* bitpos */ 481 complain_overflow_dont, /* complain_on_overflow */ 482 bfd_elf_generic_reloc, /* special_function */ 483 "R_MIPS_DELETE", /* name */ 484 false, /* partial_inplace */ 485 0, /* src_mask */ 486 0, /* dst_mask */ 487 false), /* pcrel_offset */ 488 489 /* Get the higher value of a 64 bit addend. */ 490 /* FIXME: Not handled correctly. */ 491 HOWTO (R_MIPS_HIGHER, /* type */ 492 0, /* rightshift */ 493 2, /* size (0 = byte, 1 = short, 2 = long) */ 494 16, /* bitsize */ 495 false, /* pc_relative */ 496 0, /* bitpos */ 497 complain_overflow_dont, /* complain_on_overflow */ 498 bfd_elf_generic_reloc, /* special_function */ 499 "R_MIPS_HIGHER", /* name */ 500 true, /* partial_inplace */ 501 0xffff, /* src_mask */ 502 0xffff, /* dst_mask */ 503 false), /* pcrel_offset */ 504 505 /* Get the highest value of a 64 bit addend. */ 506 /* FIXME: Not handled correctly. */ 507 HOWTO (R_MIPS_HIGHEST, /* type */ 508 0, /* rightshift */ 509 2, /* size (0 = byte, 1 = short, 2 = long) */ 510 16, /* bitsize */ 511 false, /* pc_relative */ 512 0, /* bitpos */ 513 complain_overflow_dont, /* complain_on_overflow */ 514 bfd_elf_generic_reloc, /* special_function */ 515 "R_MIPS_HIGHEST", /* name */ 516 true, /* partial_inplace */ 517 0xffff, /* src_mask */ 518 0xffff, /* dst_mask */ 519 false), /* pcrel_offset */ 520 521 /* High 16 bits of displacement in global offset table. */ 522 /* FIXME: Not handled correctly. */ 523 HOWTO (R_MIPS_CALL_HI16, /* type */ 524 0, /* rightshift */ 525 2, /* size (0 = byte, 1 = short, 2 = long) */ 526 16, /* bitsize */ 527 false, /* pc_relative */ 528 0, /* bitpos */ 529 complain_overflow_dont, /* complain_on_overflow */ 530 bfd_elf_generic_reloc, /* special_function */ 531 "R_MIPS_CALL_HI16", /* name */ 532 true, /* partial_inplace */ 533 0x0000ffff, /* src_mask */ 534 0x0000ffff, /* dst_mask */ 535 false), /* pcrel_offset */ 536 537 /* Low 16 bits of displacement in global offset table. */ 538 /* FIXME: Not handled correctly. */ 539 HOWTO (R_MIPS_CALL_LO16, /* type */ 540 0, /* rightshift */ 541 2, /* size (0 = byte, 1 = short, 2 = long) */ 542 16, /* bitsize */ 543 false, /* pc_relative */ 544 0, /* bitpos */ 545 complain_overflow_dont, /* complain_on_overflow */ 546 bfd_elf_generic_reloc, /* special_function */ 547 "R_MIPS_CALL_LO16", /* name */ 548 true, /* partial_inplace */ 549 0x0000ffff, /* src_mask */ 550 0x0000ffff, /* dst_mask */ 551 false), /* pcrel_offset */ 552 553 /* I'm not sure what the remaining relocs are, but they are defined 554 on Irix 6. */ 555 556 HOWTO (R_MIPS_SCN_DISP, /* type */ 557 0, /* rightshift */ 558 0, /* size (0 = byte, 1 = short, 2 = long) */ 559 0, /* bitsize */ 560 false, /* pc_relative */ 561 0, /* bitpos */ 562 complain_overflow_dont, /* complain_on_overflow */ 563 bfd_elf_generic_reloc, /* special_function */ 564 "R_MIPS_SCN_DISP", /* name */ 565 false, /* partial_inplace */ 566 0, /* src_mask */ 567 0, /* dst_mask */ 568 false), /* pcrel_offset */ 569 570 HOWTO (R_MIPS_REL16, /* type */ 571 0, /* rightshift */ 572 0, /* size (0 = byte, 1 = short, 2 = long) */ 573 0, /* bitsize */ 574 false, /* pc_relative */ 575 0, /* bitpos */ 576 complain_overflow_dont, /* complain_on_overflow */ 577 bfd_elf_generic_reloc, /* special_function */ 578 "R_MIPS_REL16", /* name */ 579 false, /* partial_inplace */ 580 0, /* src_mask */ 581 0, /* dst_mask */ 582 false), /* pcrel_offset */ 583 584 HOWTO (R_MIPS_ADD_IMMEDIATE, /* type */ 585 0, /* rightshift */ 586 0, /* size (0 = byte, 1 = short, 2 = long) */ 587 0, /* bitsize */ 588 false, /* pc_relative */ 589 0, /* bitpos */ 590 complain_overflow_dont, /* complain_on_overflow */ 591 bfd_elf_generic_reloc, /* special_function */ 592 "R_MIPS_ADD_IMMEDIATE", /* name */ 593 false, /* partial_inplace */ 594 0, /* src_mask */ 595 0, /* dst_mask */ 596 false), /* pcrel_offset */ 597 598 HOWTO (R_MIPS_PJUMP, /* type */ 599 0, /* rightshift */ 600 0, /* size (0 = byte, 1 = short, 2 = long) */ 601 0, /* bitsize */ 602 false, /* pc_relative */ 603 0, /* bitpos */ 604 complain_overflow_dont, /* complain_on_overflow */ 605 bfd_elf_generic_reloc, /* special_function */ 606 "R_MIPS_PJUMP", /* name */ 607 false, /* partial_inplace */ 608 0, /* src_mask */ 609 0, /* dst_mask */ 610 false), /* pcrel_offset */ 611 612 HOWTO (R_MIPS_RELGOT, /* type */ 613 0, /* rightshift */ 614 0, /* size (0 = byte, 1 = short, 2 = long) */ 615 0, /* bitsize */ 616 false, /* pc_relative */ 617 0, /* bitpos */ 618 complain_overflow_dont, /* complain_on_overflow */ 619 bfd_elf_generic_reloc, /* special_function */ 620 "R_MIPS_RELGOT", /* name */ 621 false, /* partial_inplace */ 622 0, /* src_mask */ 623 0, /* dst_mask */ 624 false), /* pcrel_offset */ 625 626 /* Protected jump conversion. This is an optimization hint. No 627 relocation is required for correctness. */ 628 HOWTO (R_MIPS_JALR, /* type */ 629 0, /* rightshift */ 630 0, /* size (0 = byte, 1 = short, 2 = long) */ 631 0, /* bitsize */ 632 false, /* pc_relative */ 633 0, /* bitpos */ 634 complain_overflow_dont, /* complain_on_overflow */ 635 bfd_elf_generic_reloc, /* special_function */ 636 "R_MIPS_JALR", /* name */ 637 false, /* partial_inplace */ 638 0x00000000, /* src_mask */ 639 0x00000000, /* dst_mask */ 640 false), /* pcrel_offset */ 641 }; 642 643 /* The relocation table used for SHT_RELA sections. */ 644 645 static reloc_howto_type mips_elf64_howto_table_rela[] = 646 { 647 /* No relocation. */ 648 HOWTO (R_MIPS_NONE, /* type */ 649 0, /* rightshift */ 650 0, /* size (0 = byte, 1 = short, 2 = long) */ 651 0, /* bitsize */ 652 false, /* pc_relative */ 653 0, /* bitpos */ 654 complain_overflow_dont, /* complain_on_overflow */ 655 bfd_elf_generic_reloc, /* special_function */ 656 "R_MIPS_NONE", /* name */ 657 false, /* partial_inplace */ 658 0, /* src_mask */ 659 0, /* dst_mask */ 660 false), /* pcrel_offset */ 661 662 /* 16 bit relocation. */ 663 HOWTO (R_MIPS_16, /* type */ 664 0, /* rightshift */ 665 1, /* size (0 = byte, 1 = short, 2 = long) */ 666 16, /* bitsize */ 667 false, /* pc_relative */ 668 0, /* bitpos */ 669 complain_overflow_bitfield, /* complain_on_overflow */ 670 bfd_elf_generic_reloc, /* special_function */ 671 "R_MIPS_16", /* name */ 672 true, /* partial_inplace */ 673 0, /* src_mask */ 674 0xffff, /* dst_mask */ 675 false), /* pcrel_offset */ 676 677 /* 32 bit relocation. */ 678 HOWTO (R_MIPS_32, /* type */ 679 0, /* rightshift */ 680 2, /* size (0 = byte, 1 = short, 2 = long) */ 681 32, /* bitsize */ 682 false, /* pc_relative */ 683 0, /* bitpos */ 684 complain_overflow_bitfield, /* complain_on_overflow */ 685 bfd_elf_generic_reloc, /* special_function */ 686 "R_MIPS_32", /* name */ 687 true, /* partial_inplace */ 688 0, /* src_mask */ 689 0xffffffff, /* dst_mask */ 690 false), /* pcrel_offset */ 691 692 /* 32 bit symbol relative relocation. */ 693 HOWTO (R_MIPS_REL32, /* type */ 694 0, /* rightshift */ 695 2, /* size (0 = byte, 1 = short, 2 = long) */ 696 32, /* bitsize */ 697 false, /* pc_relative */ 698 0, /* bitpos */ 699 complain_overflow_bitfield, /* complain_on_overflow */ 700 bfd_elf_generic_reloc, /* special_function */ 701 "R_MIPS_REL32", /* name */ 702 true, /* partial_inplace */ 703 0, /* src_mask */ 704 0xffffffff, /* dst_mask */ 705 false), /* pcrel_offset */ 706 707 /* 26 bit branch address. */ 708 HOWTO (R_MIPS_26, /* type */ 709 2, /* rightshift */ 710 2, /* size (0 = byte, 1 = short, 2 = long) */ 711 26, /* bitsize */ 712 false, /* pc_relative */ 713 0, /* bitpos */ 714 complain_overflow_dont, /* complain_on_overflow */ 715 /* This needs complex overflow 716 detection, because the upper four 717 bits must match the PC. */ 718 bfd_elf_generic_reloc, /* special_function */ 719 "R_MIPS_26", /* name */ 720 true, /* partial_inplace */ 721 0, /* src_mask */ 722 0x3ffffff, /* dst_mask */ 723 false), /* pcrel_offset */ 724 725 /* High 16 bits of symbol value. */ 726 HOWTO (R_MIPS_HI16, /* type */ 727 0, /* rightshift */ 728 2, /* size (0 = byte, 1 = short, 2 = long) */ 729 16, /* bitsize */ 730 false, /* pc_relative */ 731 0, /* bitpos */ 732 complain_overflow_dont, /* complain_on_overflow */ 733 bfd_elf_generic_reloc, /* special_function */ 734 "R_MIPS_HI16", /* name */ 735 true, /* partial_inplace */ 736 0, /* src_mask */ 737 0xffff, /* dst_mask */ 738 false), /* pcrel_offset */ 739 740 /* Low 16 bits of symbol value. */ 741 HOWTO (R_MIPS_LO16, /* type */ 742 0, /* rightshift */ 743 2, /* size (0 = byte, 1 = short, 2 = long) */ 744 16, /* bitsize */ 745 false, /* pc_relative */ 746 0, /* bitpos */ 747 complain_overflow_dont, /* complain_on_overflow */ 748 bfd_elf_generic_reloc, /* special_function */ 749 "R_MIPS_LO16", /* name */ 750 true, /* partial_inplace */ 751 0, /* src_mask */ 752 0xffff, /* dst_mask */ 753 false), /* pcrel_offset */ 754 755 /* GP relative reference. */ 756 HOWTO (R_MIPS_GPREL16, /* type */ 757 0, /* rightshift */ 758 2, /* size (0 = byte, 1 = short, 2 = long) */ 759 16, /* bitsize */ 760 false, /* pc_relative */ 761 0, /* bitpos */ 762 complain_overflow_signed, /* complain_on_overflow */ 763 _bfd_mips_elf_gprel16_reloc, /* special_function */ 764 "R_MIPS_GPREL16", /* name */ 765 true, /* partial_inplace */ 766 0, /* src_mask */ 767 0xffff, /* dst_mask */ 768 false), /* pcrel_offset */ 769 770 /* Reference to literal section. */ 771 HOWTO (R_MIPS_LITERAL, /* type */ 772 0, /* rightshift */ 773 2, /* size (0 = byte, 1 = short, 2 = long) */ 774 16, /* bitsize */ 775 false, /* pc_relative */ 776 0, /* bitpos */ 777 complain_overflow_signed, /* complain_on_overflow */ 778 _bfd_mips_elf_gprel16_reloc, /* special_function */ 779 "R_MIPS_LITERAL", /* name */ 780 true, /* partial_inplace */ 781 0, /* src_mask */ 782 0xffff, /* dst_mask */ 783 false), /* pcrel_offset */ 784 785 /* Reference to global offset table. */ 786 /* FIXME: This is not handled correctly. */ 787 HOWTO (R_MIPS_GOT16, /* type */ 788 0, /* rightshift */ 789 2, /* size (0 = byte, 1 = short, 2 = long) */ 790 16, /* bitsize */ 791 false, /* pc_relative */ 792 0, /* bitpos */ 793 complain_overflow_signed, /* complain_on_overflow */ 794 bfd_elf_generic_reloc, /* special_function */ 795 "R_MIPS_GOT16", /* name */ 796 false, /* partial_inplace */ 797 0, /* src_mask */ 798 0xffff, /* dst_mask */ 799 false), /* pcrel_offset */ 800 801 /* 16 bit PC relative reference. */ 802 HOWTO (R_MIPS_PC16, /* type */ 803 0, /* rightshift */ 804 2, /* size (0 = byte, 1 = short, 2 = long) */ 805 16, /* bitsize */ 806 true, /* pc_relative */ 807 0, /* bitpos */ 808 complain_overflow_signed, /* complain_on_overflow */ 809 bfd_elf_generic_reloc, /* special_function */ 810 "R_MIPS_PC16", /* name */ 811 true, /* partial_inplace */ 812 0, /* src_mask */ 813 0xffff, /* dst_mask */ 814 false), /* pcrel_offset */ 815 816 /* 16 bit call through global offset table. */ 817 /* FIXME: This is not handled correctly. */ 818 HOWTO (R_MIPS_CALL16, /* type */ 819 0, /* rightshift */ 820 2, /* size (0 = byte, 1 = short, 2 = long) */ 821 16, /* bitsize */ 822 false, /* pc_relative */ 823 0, /* bitpos */ 824 complain_overflow_signed, /* complain_on_overflow */ 825 bfd_elf_generic_reloc, /* special_function */ 826 "R_MIPS_CALL16", /* name */ 827 false, /* partial_inplace */ 828 0, /* src_mask */ 829 0xffff, /* dst_mask */ 830 false), /* pcrel_offset */ 831 832 /* 32 bit GP relative reference. */ 833 HOWTO (R_MIPS_GPREL32, /* type */ 834 0, /* rightshift */ 835 2, /* size (0 = byte, 1 = short, 2 = long) */ 836 32, /* bitsize */ 837 false, /* pc_relative */ 838 0, /* bitpos */ 839 complain_overflow_bitfield, /* complain_on_overflow */ 840 _bfd_mips_elf_gprel32_reloc, /* special_function */ 841 "R_MIPS_GPREL32", /* name */ 842 true, /* partial_inplace */ 843 0, /* src_mask */ 844 0xffffffff, /* dst_mask */ 845 false), /* pcrel_offset */ 846 847 { 13 }, 848 { 14 }, 849 { 15 }, 850 851 /* A 5 bit shift field. */ 852 HOWTO (R_MIPS_SHIFT5, /* type */ 853 0, /* rightshift */ 854 2, /* size (0 = byte, 1 = short, 2 = long) */ 855 5, /* bitsize */ 856 false, /* pc_relative */ 857 6, /* bitpos */ 858 complain_overflow_bitfield, /* complain_on_overflow */ 859 bfd_elf_generic_reloc, /* special_function */ 860 "R_MIPS_SHIFT5", /* name */ 861 true, /* partial_inplace */ 862 0, /* src_mask */ 863 0x000007c0, /* dst_mask */ 864 false), /* pcrel_offset */ 865 866 /* A 6 bit shift field. */ 867 /* FIXME: This is not handled correctly; a special function is 868 needed to put the most significant bit in the right place. */ 869 HOWTO (R_MIPS_SHIFT6, /* type */ 870 0, /* rightshift */ 871 2, /* size (0 = byte, 1 = short, 2 = long) */ 872 6, /* bitsize */ 873 false, /* pc_relative */ 874 6, /* bitpos */ 875 complain_overflow_bitfield, /* complain_on_overflow */ 876 bfd_elf_generic_reloc, /* special_function */ 877 "R_MIPS_SHIFT6", /* name */ 878 true, /* partial_inplace */ 879 0, /* src_mask */ 880 0x000007c4, /* dst_mask */ 881 false), /* pcrel_offset */ 882 883 /* 64 bit relocation. */ 884 HOWTO (R_MIPS_64, /* type */ 885 0, /* rightshift */ 886 4, /* size (0 = byte, 1 = short, 2 = long) */ 887 64, /* bitsize */ 888 false, /* pc_relative */ 889 0, /* bitpos */ 890 complain_overflow_bitfield, /* complain_on_overflow */ 891 bfd_elf_generic_reloc, /* special_function */ 892 "R_MIPS_64", /* name */ 893 true, /* partial_inplace */ 894 0, /* src_mask */ 895 MINUS_ONE, /* dst_mask */ 896 false), /* pcrel_offset */ 897 898 /* Displacement in the global offset table. */ 899 /* FIXME: Not handled correctly. */ 900 HOWTO (R_MIPS_GOT_DISP, /* type */ 901 0, /* rightshift */ 902 2, /* size (0 = byte, 1 = short, 2 = long) */ 903 16, /* bitsize */ 904 false, /* pc_relative */ 905 0, /* bitpos */ 906 complain_overflow_bitfield, /* complain_on_overflow */ 907 bfd_elf_generic_reloc, /* special_function */ 908 "R_MIPS_GOT_DISP", /* name */ 909 true, /* partial_inplace */ 910 0, /* src_mask */ 911 0x0000ffff, /* dst_mask */ 912 false), /* pcrel_offset */ 913 914 /* Displacement to page pointer in the global offset table. */ 915 /* FIXME: Not handled correctly. */ 916 HOWTO (R_MIPS_GOT_PAGE, /* type */ 917 0, /* rightshift */ 918 2, /* size (0 = byte, 1 = short, 2 = long) */ 919 16, /* bitsize */ 920 false, /* pc_relative */ 921 0, /* bitpos */ 922 complain_overflow_bitfield, /* complain_on_overflow */ 923 bfd_elf_generic_reloc, /* special_function */ 924 "R_MIPS_GOT_PAGE", /* name */ 925 true, /* partial_inplace */ 926 0, /* src_mask */ 927 0x0000ffff, /* dst_mask */ 928 false), /* pcrel_offset */ 929 930 /* Offset from page pointer in the global offset table. */ 931 /* FIXME: Not handled correctly. */ 932 HOWTO (R_MIPS_GOT_OFST, /* type */ 933 0, /* rightshift */ 934 2, /* size (0 = byte, 1 = short, 2 = long) */ 935 16, /* bitsize */ 936 false, /* pc_relative */ 937 0, /* bitpos */ 938 complain_overflow_bitfield, /* complain_on_overflow */ 939 bfd_elf_generic_reloc, /* special_function */ 940 "R_MIPS_GOT_OFST", /* name */ 941 true, /* partial_inplace */ 942 0, /* src_mask */ 943 0x0000ffff, /* dst_mask */ 944 false), /* pcrel_offset */ 945 946 /* High 16 bits of displacement in global offset table. */ 947 /* FIXME: Not handled correctly. */ 948 HOWTO (R_MIPS_GOT_HI16, /* type */ 949 0, /* rightshift */ 950 2, /* size (0 = byte, 1 = short, 2 = long) */ 951 16, /* bitsize */ 952 false, /* pc_relative */ 953 0, /* bitpos */ 954 complain_overflow_dont, /* complain_on_overflow */ 955 bfd_elf_generic_reloc, /* special_function */ 956 "R_MIPS_GOT_HI16", /* name */ 957 true, /* partial_inplace */ 958 0, /* src_mask */ 959 0x0000ffff, /* dst_mask */ 960 false), /* pcrel_offset */ 961 962 /* Low 16 bits of displacement in global offset table. */ 963 /* FIXME: Not handled correctly. */ 964 HOWTO (R_MIPS_GOT_LO16, /* type */ 965 0, /* rightshift */ 966 2, /* size (0 = byte, 1 = short, 2 = long) */ 967 16, /* bitsize */ 968 false, /* pc_relative */ 969 0, /* bitpos */ 970 complain_overflow_dont, /* complain_on_overflow */ 971 bfd_elf_generic_reloc, /* special_function */ 972 "R_MIPS_GOT_LO16", /* name */ 973 true, /* partial_inplace */ 974 0, /* src_mask */ 975 0x0000ffff, /* dst_mask */ 976 false), /* pcrel_offset */ 977 978 /* 64 bit substraction. */ 979 /* FIXME: Not handled correctly. */ 980 HOWTO (R_MIPS_SUB, /* type */ 981 0, /* rightshift */ 982 4, /* size (0 = byte, 1 = short, 2 = long) */ 983 64, /* bitsize */ 984 false, /* pc_relative */ 985 0, /* bitpos */ 986 complain_overflow_bitfield, /* complain_on_overflow */ 987 bfd_elf_generic_reloc, /* special_function */ 988 "R_MIPS_SUB", /* name */ 989 true, /* partial_inplace */ 990 0, /* src_mask */ 991 MINUS_ONE, /* dst_mask */ 992 false), /* pcrel_offset */ 993 994 /* Insert the addend as an instruction. */ 995 /* FIXME: Not handled correctly. */ 996 HOWTO (R_MIPS_INSERT_A, /* type */ 997 0, /* rightshift */ 998 0, /* size (0 = byte, 1 = short, 2 = long) */ 999 0, /* bitsize */ 1000 false, /* pc_relative */ 1001 0, /* bitpos */ 1002 complain_overflow_dont, /* complain_on_overflow */ 1003 bfd_elf_generic_reloc, /* special_function */ 1004 "R_MIPS_INSERT_A", /* name */ 1005 false, /* partial_inplace */ 1006 0, /* src_mask */ 1007 0, /* dst_mask */ 1008 false), /* pcrel_offset */ 1009 1010 /* Insert the addend as an instruction, and change all relocations 1011 to refer to the old instruction at the address. */ 1012 /* FIXME: Not handled correctly. */ 1013 HOWTO (R_MIPS_INSERT_B, /* type */ 1014 0, /* rightshift */ 1015 0, /* size (0 = byte, 1 = short, 2 = long) */ 1016 0, /* bitsize */ 1017 false, /* pc_relative */ 1018 0, /* bitpos */ 1019 complain_overflow_dont, /* complain_on_overflow */ 1020 bfd_elf_generic_reloc, /* special_function */ 1021 "R_MIPS_INSERT_B", /* name */ 1022 false, /* partial_inplace */ 1023 0, /* src_mask */ 1024 0, /* dst_mask */ 1025 false), /* pcrel_offset */ 1026 1027 /* Delete a 32 bit instruction. */ 1028 /* FIXME: Not handled correctly. */ 1029 HOWTO (R_MIPS_DELETE, /* type */ 1030 0, /* rightshift */ 1031 0, /* size (0 = byte, 1 = short, 2 = long) */ 1032 0, /* bitsize */ 1033 false, /* pc_relative */ 1034 0, /* bitpos */ 1035 complain_overflow_dont, /* complain_on_overflow */ 1036 bfd_elf_generic_reloc, /* special_function */ 1037 "R_MIPS_DELETE", /* name */ 1038 false, /* partial_inplace */ 1039 0, /* src_mask */ 1040 0, /* dst_mask */ 1041 false), /* pcrel_offset */ 1042 1043 /* Get the higher value of a 64 bit addend. */ 1044 /* FIXME: Not handled correctly. */ 1045 HOWTO (R_MIPS_HIGHER, /* type */ 1046 0, /* rightshift */ 1047 2, /* size (0 = byte, 1 = short, 2 = long) */ 1048 16, /* bitsize */ 1049 false, /* pc_relative */ 1050 0, /* bitpos */ 1051 complain_overflow_dont, /* complain_on_overflow */ 1052 bfd_elf_generic_reloc, /* special_function */ 1053 "R_MIPS_HIGHER", /* name */ 1054 true, /* partial_inplace */ 1055 0, /* src_mask */ 1056 0xffff, /* dst_mask */ 1057 false), /* pcrel_offset */ 1058 1059 /* Get the highest value of a 64 bit addend. */ 1060 /* FIXME: Not handled correctly. */ 1061 HOWTO (R_MIPS_HIGHEST, /* type */ 1062 0, /* rightshift */ 1063 2, /* size (0 = byte, 1 = short, 2 = long) */ 1064 16, /* bitsize */ 1065 false, /* pc_relative */ 1066 0, /* bitpos */ 1067 complain_overflow_dont, /* complain_on_overflow */ 1068 bfd_elf_generic_reloc, /* special_function */ 1069 "R_MIPS_HIGHEST", /* name */ 1070 true, /* partial_inplace */ 1071 0, /* src_mask */ 1072 0xffff, /* dst_mask */ 1073 false), /* pcrel_offset */ 1074 1075 /* High 16 bits of displacement in global offset table. */ 1076 /* FIXME: Not handled correctly. */ 1077 HOWTO (R_MIPS_CALL_HI16, /* type */ 1078 0, /* rightshift */ 1079 2, /* size (0 = byte, 1 = short, 2 = long) */ 1080 16, /* bitsize */ 1081 false, /* pc_relative */ 1082 0, /* bitpos */ 1083 complain_overflow_dont, /* complain_on_overflow */ 1084 bfd_elf_generic_reloc, /* special_function */ 1085 "R_MIPS_CALL_HI16", /* name */ 1086 true, /* partial_inplace */ 1087 0, /* src_mask */ 1088 0x0000ffff, /* dst_mask */ 1089 false), /* pcrel_offset */ 1090 1091 /* Low 16 bits of displacement in global offset table. */ 1092 /* FIXME: Not handled correctly. */ 1093 HOWTO (R_MIPS_CALL_LO16, /* 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_dont, /* complain_on_overflow */ 1100 bfd_elf_generic_reloc, /* special_function */ 1101 "R_MIPS_CALL_LO16", /* name */ 1102 true, /* partial_inplace */ 1103 0, /* src_mask */ 1104 0x0000ffff, /* dst_mask */ 1105 false), /* pcrel_offset */ 1106 1107 /* I'm not sure what the remaining relocs are, but they are defined 1108 on Irix 6. */ 1109 1110 HOWTO (R_MIPS_SCN_DISP, /* type */ 1111 0, /* rightshift */ 1112 0, /* size (0 = byte, 1 = short, 2 = long) */ 1113 0, /* bitsize */ 1114 false, /* pc_relative */ 1115 0, /* bitpos */ 1116 complain_overflow_dont, /* complain_on_overflow */ 1117 bfd_elf_generic_reloc, /* special_function */ 1118 "R_MIPS_SCN_DISP", /* name */ 1119 false, /* partial_inplace */ 1120 0, /* src_mask */ 1121 0, /* dst_mask */ 1122 false), /* pcrel_offset */ 1123 1124 HOWTO (R_MIPS_REL16, /* type */ 1125 0, /* rightshift */ 1126 0, /* size (0 = byte, 1 = short, 2 = long) */ 1127 0, /* bitsize */ 1128 false, /* pc_relative */ 1129 0, /* bitpos */ 1130 complain_overflow_dont, /* complain_on_overflow */ 1131 bfd_elf_generic_reloc, /* special_function */ 1132 "R_MIPS_REL16", /* name */ 1133 false, /* partial_inplace */ 1134 0, /* src_mask */ 1135 0, /* dst_mask */ 1136 false), /* pcrel_offset */ 1137 1138 HOWTO (R_MIPS_ADD_IMMEDIATE, /* type */ 1139 0, /* rightshift */ 1140 0, /* size (0 = byte, 1 = short, 2 = long) */ 1141 0, /* bitsize */ 1142 false, /* pc_relative */ 1143 0, /* bitpos */ 1144 complain_overflow_dont, /* complain_on_overflow */ 1145 bfd_elf_generic_reloc, /* special_function */ 1146 "R_MIPS_ADD_IMMEDIATE", /* name */ 1147 false, /* partial_inplace */ 1148 0, /* src_mask */ 1149 0, /* dst_mask */ 1150 false), /* pcrel_offset */ 1151 1152 HOWTO (R_MIPS_PJUMP, /* type */ 1153 0, /* rightshift */ 1154 0, /* size (0 = byte, 1 = short, 2 = long) */ 1155 0, /* bitsize */ 1156 false, /* pc_relative */ 1157 0, /* bitpos */ 1158 complain_overflow_dont, /* complain_on_overflow */ 1159 bfd_elf_generic_reloc, /* special_function */ 1160 "R_MIPS_PJUMP", /* name */ 1161 false, /* partial_inplace */ 1162 0, /* src_mask */ 1163 0, /* dst_mask */ 1164 false), /* pcrel_offset */ 1165 1166 HOWTO (R_MIPS_RELGOT, /* type */ 1167 0, /* rightshift */ 1168 0, /* size (0 = byte, 1 = short, 2 = long) */ 1169 0, /* bitsize */ 1170 false, /* pc_relative */ 1171 0, /* bitpos */ 1172 complain_overflow_dont, /* complain_on_overflow */ 1173 bfd_elf_generic_reloc, /* special_function */ 1174 "R_MIPS_RELGOT", /* name */ 1175 false, /* partial_inplace */ 1176 0, /* src_mask */ 1177 0, /* dst_mask */ 1178 false), /* pcrel_offset */ 1179 1180 /* Protected jump conversion. This is an optimization hint. No 1181 relocation is required for correctness. */ 1182 HOWTO (R_MIPS_JALR, /* type */ 1183 0, /* rightshift */ 1184 0, /* size (0 = byte, 1 = short, 2 = long) */ 1185 0, /* bitsize */ 1186 false, /* pc_relative */ 1187 0, /* bitpos */ 1188 complain_overflow_dont, /* complain_on_overflow */ 1189 bfd_elf_generic_reloc, /* special_function */ 1190 "R_MIPS_JALR", /* name */ 1191 false, /* partial_inplace */ 1192 0x00000000, /* src_mask */ 1193 0x00000000, /* dst_mask */ 1194 false), /* pcrel_offset */ 1195 }; 1196 1197 /* Swap in a MIPS 64-bit Rel reloc. */ 1198 1199 static void 1200 mips_elf64_swap_reloc_in (abfd, src, dst) 1201 bfd *abfd; 1202 const Elf64_Mips_External_Rel *src; 1203 Elf64_Mips_Internal_Rel *dst; 1204 { 1205 dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset); 1206 dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym); 1207 dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym); 1208 dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3); 1209 dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2); 1210 dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type); 1211 } 1212 1213 /* Swap in a MIPS 64-bit Rela reloc. */ 1214 1215 static void 1216 mips_elf64_swap_reloca_in (abfd, src, dst) 1217 bfd *abfd; 1218 const Elf64_Mips_External_Rela *src; 1219 Elf64_Mips_Internal_Rela *dst; 1220 { 1221 dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset); 1222 dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym); 1223 dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym); 1224 dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3); 1225 dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2); 1226 dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type); 1227 dst->r_addend = bfd_h_get_signed_64 (abfd, (bfd_byte *) src->r_addend); 1228 } 1229 1230 /* Swap out a MIPS 64-bit Rel reloc. */ 1231 1232 static void 1233 mips_elf64_swap_reloc_out (abfd, src, dst) 1234 bfd *abfd; 1235 const Elf64_Mips_Internal_Rel *src; 1236 Elf64_Mips_External_Rel *dst; 1237 { 1238 bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset); 1239 bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym); 1240 bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym); 1241 bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3); 1242 bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2); 1243 bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type); 1244 } 1245 1246 /* Swap out a MIPS 64-bit Rela reloc. */ 1247 1248 static void 1249 mips_elf64_swap_reloca_out (abfd, src, dst) 1250 bfd *abfd; 1251 const Elf64_Mips_Internal_Rela *src; 1252 Elf64_Mips_External_Rela *dst; 1253 { 1254 bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset); 1255 bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym); 1256 bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym); 1257 bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3); 1258 bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2); 1259 bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type); 1260 bfd_h_put_64 (abfd, src->r_addend, (bfd_byte *) dst->r_addend); 1261 } 1262 1263 /* Swap in a MIPS 64-bit Rel reloc. */ 1264 1265 static void 1266 mips_elf64_be_swap_reloc_in (abfd, src, dst) 1267 bfd *abfd; 1268 const bfd_byte *src; 1269 Elf_Internal_Rel *dst; 1270 { 1271 Elf64_Mips_Internal_Rel mirel; 1272 1273 mips_elf64_swap_reloc_in (abfd, 1274 (const Elf64_Mips_External_Rel *) src, 1275 &mirel); 1276 1277 dst[0].r_offset = mirel.r_offset; 1278 dst[0].r_info = ELF32_R_INFO (mirel.r_sym, mirel.r_type); 1279 dst[1].r_offset = mirel.r_offset; 1280 dst[1].r_info = ELF32_R_INFO (mirel.r_ssym, mirel.r_type2); 1281 dst[2].r_offset = mirel.r_offset; 1282 dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirel.r_type3); 1283 } 1284 1285 /* Swap in a MIPS 64-bit Rela reloc. */ 1286 1287 static void 1288 mips_elf64_be_swap_reloca_in (abfd, src, dst) 1289 bfd *abfd; 1290 const bfd_byte *src; 1291 Elf_Internal_Rela *dst; 1292 { 1293 Elf64_Mips_Internal_Rela mirela; 1294 1295 mips_elf64_swap_reloca_in (abfd, 1296 (const Elf64_Mips_External_Rela *) src, 1297 &mirela); 1298 1299 dst[0].r_offset = mirela.r_offset; 1300 dst[0].r_info = ELF32_R_INFO (mirela.r_sym, mirela.r_type); 1301 dst[0].r_addend = mirela.r_addend; 1302 dst[1].r_offset = mirela.r_offset; 1303 dst[1].r_info = ELF32_R_INFO (mirela.r_ssym, mirela.r_type2); 1304 dst[1].r_addend = 0; 1305 dst[2].r_offset = mirela.r_offset; 1306 dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirela.r_type3); 1307 dst[2].r_addend = 0; 1308 } 1309 1310 /* Swap out a MIPS 64-bit Rel reloc. */ 1311 1312 static void 1313 mips_elf64_be_swap_reloc_out (abfd, src, dst) 1314 bfd *abfd; 1315 const Elf_Internal_Rel *src; 1316 bfd_byte *dst; 1317 { 1318 Elf64_Mips_Internal_Rel mirel; 1319 1320 mirel.r_offset = src->r_offset; 1321 mirel.r_type = ELF32_R_TYPE (src->r_info); 1322 mirel.r_sym = ELF32_R_SYM (src->r_info); 1323 mirel.r_type2 = R_MIPS_NONE; 1324 mirel.r_ssym = STN_UNDEF; 1325 mirel.r_type3 = R_MIPS_NONE; 1326 1327 mips_elf64_swap_reloc_out (abfd, &mirel, 1328 (Elf64_Mips_External_Rel *) dst); 1329 } 1330 1331 /* Swap out a MIPS 64-bit Rela reloc. */ 1332 1333 static void 1334 mips_elf64_be_swap_reloca_out (abfd, src, dst) 1335 bfd *abfd; 1336 const Elf_Internal_Rela *src; 1337 bfd_byte *dst; 1338 { 1339 Elf64_Mips_Internal_Rela mirela; 1340 1341 mirela.r_offset = src->r_offset; 1342 mirela.r_type = ELF32_R_TYPE (src->r_info); 1343 mirela.r_addend = src->r_addend; 1344 mirela.r_sym = ELF32_R_SYM (src->r_info); 1345 mirela.r_type2 = R_MIPS_NONE; 1346 mirela.r_ssym = STN_UNDEF; 1347 mirela.r_type3 = R_MIPS_NONE; 1348 1349 mips_elf64_swap_reloca_out (abfd, &mirela, 1350 (Elf64_Mips_External_Rela *) dst); 1351 } 1352 1353 /* A mapping from BFD reloc types to MIPS ELF reloc types. */ 1354 1355 struct elf_reloc_map 1356 { 1357 bfd_reloc_code_real_type bfd_reloc_val; 1358 enum elf_mips_reloc_type elf_reloc_val; 1359 }; 1360 1361 static CONST struct elf_reloc_map mips_reloc_map[] = 1362 { 1363 { BFD_RELOC_NONE, R_MIPS_NONE, }, 1364 { BFD_RELOC_16, R_MIPS_16 }, 1365 { BFD_RELOC_32, R_MIPS_32 }, 1366 { BFD_RELOC_64, R_MIPS_64 }, 1367 { BFD_RELOC_CTOR, R_MIPS_64 }, 1368 { BFD_RELOC_32_PCREL, R_MIPS_REL32 }, 1369 { BFD_RELOC_MIPS_JMP, R_MIPS_26 }, 1370 { BFD_RELOC_HI16_S, R_MIPS_HI16 }, 1371 { BFD_RELOC_LO16, R_MIPS_LO16 }, 1372 { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 }, 1373 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL }, 1374 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 }, 1375 { BFD_RELOC_16_PCREL, R_MIPS_PC16 }, 1376 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 }, 1377 { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 }, 1378 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 }, 1379 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 }, 1380 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 }, 1381 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 }, 1382 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB }, 1383 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE }, 1384 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST }, 1385 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP } 1386 }; 1387 1388 /* Given a BFD reloc type, return a howto structure. */ 1389 1390 static reloc_howto_type * 1391 mips_elf64_reloc_type_lookup (abfd, code) 1392 bfd *abfd; 1393 bfd_reloc_code_real_type code; 1394 { 1395 unsigned int i; 1396 1397 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++) 1398 { 1399 if (mips_reloc_map[i].bfd_reloc_val == code) 1400 { 1401 int v; 1402 1403 v = (int) mips_reloc_map[i].elf_reloc_val; 1404 return &mips_elf64_howto_table_rel[v]; 1405 } 1406 } 1407 1408 return NULL; 1409 } 1410 1411 /* Since each entry in an SHT_REL or SHT_RELA section can represent up 1412 to three relocs, we must tell the user to allocate more space. */ 1413 1414 static long 1415 mips_elf64_get_reloc_upper_bound (abfd, sec) 1416 bfd *abfd; 1417 asection *sec; 1418 { 1419 return (sec->reloc_count * 3 + 1) * sizeof (arelent *); 1420 } 1421 1422 /* Read the relocations from one reloc section. */ 1423 1424 static boolean 1425 mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr) 1426 bfd *abfd; 1427 asection *asect; 1428 asymbol **symbols; 1429 const Elf_Internal_Shdr *rel_hdr; 1430 { 1431 PTR allocated = NULL; 1432 bfd_byte *native_relocs; 1433 arelent *relents; 1434 arelent *relent; 1435 unsigned int count; 1436 unsigned int i; 1437 int entsize; 1438 reloc_howto_type *howto_table; 1439 1440 allocated = (PTR) bfd_malloc (rel_hdr->sh_size); 1441 if (allocated == NULL) 1442 goto error_return; 1443 1444 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0 1445 || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)) 1446 goto error_return; 1447 1448 native_relocs = (bfd_byte *) allocated; 1449 1450 relents = asect->relocation + asect->reloc_count; 1451 1452 entsize = rel_hdr->sh_entsize; 1453 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel) 1454 || entsize == sizeof (Elf64_Mips_External_Rela)); 1455 1456 count = rel_hdr->sh_size / entsize; 1457 1458 if (entsize == sizeof (Elf64_Mips_External_Rel)) 1459 howto_table = mips_elf64_howto_table_rel; 1460 else 1461 howto_table = mips_elf64_howto_table_rela; 1462 1463 relent = relents; 1464 for (i = 0; i < count; i++, native_relocs += entsize) 1465 { 1466 Elf64_Mips_Internal_Rela rela; 1467 boolean used_sym, used_ssym; 1468 int ir; 1469 1470 if (entsize == sizeof (Elf64_Mips_External_Rela)) 1471 mips_elf64_swap_reloca_in (abfd, 1472 (Elf64_Mips_External_Rela *) native_relocs, 1473 &rela); 1474 else 1475 { 1476 Elf64_Mips_Internal_Rel rel; 1477 1478 mips_elf64_swap_reloc_in (abfd, 1479 (Elf64_Mips_External_Rel *) native_relocs, 1480 &rel); 1481 rela.r_offset = rel.r_offset; 1482 rela.r_sym = rel.r_sym; 1483 rela.r_ssym = rel.r_ssym; 1484 rela.r_type3 = rel.r_type3; 1485 rela.r_type2 = rel.r_type2; 1486 rela.r_type = rel.r_type; 1487 rela.r_addend = 0; 1488 } 1489 1490 /* Each entry represents up to three actual relocations. */ 1491 1492 used_sym = false; 1493 used_ssym = false; 1494 for (ir = 0; ir < 3; ir++) 1495 { 1496 enum elf_mips_reloc_type type; 1497 1498 switch (ir) 1499 { 1500 default: 1501 abort (); 1502 case 0: 1503 type = (enum elf_mips_reloc_type) rela.r_type; 1504 break; 1505 case 1: 1506 type = (enum elf_mips_reloc_type) rela.r_type2; 1507 break; 1508 case 2: 1509 type = (enum elf_mips_reloc_type) rela.r_type3; 1510 break; 1511 } 1512 1513 if (type == R_MIPS_NONE) 1514 { 1515 /* There are no more relocations in this entry. If this 1516 is the first entry, we need to generate a dummy 1517 relocation so that the generic linker knows that 1518 there has been a break in the sequence of relocations 1519 applying to a particular address. */ 1520 if (ir == 0) 1521 { 1522 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 1523 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) 1524 relent->address = rela.r_offset; 1525 else 1526 relent->address = rela.r_offset - asect->vma; 1527 relent->addend = 0; 1528 relent->howto = &howto_table[(int) R_MIPS_NONE]; 1529 ++relent; 1530 } 1531 break; 1532 } 1533 1534 /* Some types require symbols, whereas some do not. */ 1535 switch (type) 1536 { 1537 case R_MIPS_NONE: 1538 case R_MIPS_LITERAL: 1539 case R_MIPS_INSERT_A: 1540 case R_MIPS_INSERT_B: 1541 case R_MIPS_DELETE: 1542 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 1543 break; 1544 1545 default: 1546 if (! used_sym) 1547 { 1548 if (rela.r_sym == 0) 1549 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 1550 else 1551 { 1552 asymbol **ps, *s; 1553 1554 ps = symbols + rela.r_sym - 1; 1555 s = *ps; 1556 if ((s->flags & BSF_SECTION_SYM) == 0) 1557 relent->sym_ptr_ptr = ps; 1558 else 1559 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; 1560 } 1561 1562 used_sym = true; 1563 } 1564 else if (! used_ssym) 1565 { 1566 switch (rela.r_ssym) 1567 { 1568 case RSS_UNDEF: 1569 relent->sym_ptr_ptr = 1570 bfd_abs_section_ptr->symbol_ptr_ptr; 1571 break; 1572 1573 case RSS_GP: 1574 case RSS_GP0: 1575 case RSS_LOC: 1576 /* FIXME: I think these need to be handled using 1577 special howto structures. */ 1578 BFD_ASSERT (0); 1579 break; 1580 1581 default: 1582 BFD_ASSERT (0); 1583 break; 1584 } 1585 1586 used_ssym = true; 1587 } 1588 else 1589 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 1590 1591 break; 1592 } 1593 1594 /* The address of an ELF reloc is section relative for an 1595 object file, and absolute for an executable file or 1596 shared library. The address of a BFD reloc is always 1597 section relative. */ 1598 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) 1599 relent->address = rela.r_offset; 1600 else 1601 relent->address = rela.r_offset - asect->vma; 1602 1603 relent->addend = rela.r_addend; 1604 1605 relent->howto = &howto_table[(int) type]; 1606 1607 ++relent; 1608 } 1609 } 1610 1611 asect->reloc_count += relent - relents; 1612 1613 if (allocated != NULL) 1614 free (allocated); 1615 1616 return true; 1617 1618 error_return: 1619 if (allocated != NULL) 1620 free (allocated); 1621 return false; 1622 } 1623 1624 /* Read the relocations. On Irix 6, there can be two reloc sections 1625 associated with a single data section. */ 1626 1627 static boolean 1628 mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic) 1629 bfd *abfd; 1630 asection *asect; 1631 asymbol **symbols; 1632 boolean dynamic; 1633 { 1634 struct bfd_elf_section_data * const d = elf_section_data (asect); 1635 1636 if (dynamic) 1637 { 1638 bfd_set_error (bfd_error_invalid_operation); 1639 return false; 1640 } 1641 1642 if (asect->relocation != NULL 1643 || (asect->flags & SEC_RELOC) == 0 1644 || asect->reloc_count == 0) 1645 return true; 1646 1647 /* Allocate space for 3 arelent structures for each Rel structure. */ 1648 asect->relocation = ((arelent *) 1649 bfd_alloc (abfd, 1650 asect->reloc_count * 3 * sizeof (arelent))); 1651 if (asect->relocation == NULL) 1652 return false; 1653 1654 /* The slurp_one_reloc_table routine increments reloc_count. */ 1655 asect->reloc_count = 0; 1656 1657 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr)) 1658 return false; 1659 if (d->rel_hdr2 != NULL) 1660 { 1661 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, 1662 d->rel_hdr2)) 1663 return false; 1664 } 1665 1666 return true; 1667 } 1668 1669 /* Write out the relocations. */ 1670 1671 static void 1672 mips_elf64_write_relocs (abfd, sec, data) 1673 bfd *abfd; 1674 asection *sec; 1675 PTR data; 1676 { 1677 boolean *failedp = (boolean *) data; 1678 unsigned int count; 1679 Elf_Internal_Shdr *rela_hdr; 1680 Elf64_Mips_External_Rela *ext_rela; 1681 unsigned int idx; 1682 asymbol *last_sym = 0; 1683 int last_sym_idx = 0; 1684 1685 /* If we have already failed, don't do anything. */ 1686 if (*failedp) 1687 return; 1688 1689 if ((sec->flags & SEC_RELOC) == 0) 1690 return; 1691 1692 /* The linker backend writes the relocs out itself, and sets the 1693 reloc_count field to zero to inhibit writing them here. Also, 1694 sometimes the SEC_RELOC flag gets set even when there aren't any 1695 relocs. */ 1696 if (sec->reloc_count == 0) 1697 return; 1698 1699 /* We can combine up to three relocs that refer to the same address 1700 if the latter relocs have no associated symbol. */ 1701 count = 0; 1702 for (idx = 0; idx < sec->reloc_count; idx++) 1703 { 1704 bfd_vma addr; 1705 unsigned int i; 1706 1707 ++count; 1708 1709 addr = sec->orelocation[idx]->address; 1710 for (i = 0; i < 2; i++) 1711 { 1712 arelent *r; 1713 1714 if (idx + 1 >= sec->reloc_count) 1715 break; 1716 r = sec->orelocation[idx + 1]; 1717 if (r->address != addr 1718 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section) 1719 || (*r->sym_ptr_ptr)->value != 0) 1720 break; 1721 1722 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */ 1723 1724 ++idx; 1725 } 1726 } 1727 1728 rela_hdr = &elf_section_data (sec)->rel_hdr; 1729 1730 rela_hdr->sh_size = rela_hdr->sh_entsize * count; 1731 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size); 1732 if (rela_hdr->contents == NULL) 1733 { 1734 *failedp = true; 1735 return; 1736 } 1737 1738 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents; 1739 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++) 1740 { 1741 arelent *ptr; 1742 Elf64_Mips_Internal_Rela int_rela; 1743 asymbol *sym; 1744 int n; 1745 unsigned int i; 1746 1747 ptr = sec->orelocation[idx]; 1748 1749 /* The address of an ELF reloc is section relative for an object 1750 file, and absolute for an executable file or shared library. 1751 The address of a BFD reloc is always section relative. */ 1752 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) 1753 int_rela.r_offset = ptr->address; 1754 else 1755 int_rela.r_offset = ptr->address + sec->vma; 1756 1757 sym = *ptr->sym_ptr_ptr; 1758 if (sym == last_sym) 1759 n = last_sym_idx; 1760 else 1761 { 1762 last_sym = sym; 1763 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); 1764 if (n < 0) 1765 { 1766 *failedp = true; 1767 return; 1768 } 1769 last_sym_idx = n; 1770 } 1771 1772 int_rela.r_sym = n; 1773 1774 int_rela.r_addend = ptr->addend; 1775 1776 int_rela.r_ssym = RSS_UNDEF; 1777 1778 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec 1779 && ! _bfd_elf_validate_reloc (abfd, ptr)) 1780 { 1781 *failedp = true; 1782 return; 1783 } 1784 1785 int_rela.r_type = ptr->howto->type; 1786 int_rela.r_type2 = (int) R_MIPS_NONE; 1787 int_rela.r_type3 = (int) R_MIPS_NONE; 1788 1789 for (i = 0; i < 2; i++) 1790 { 1791 arelent *r; 1792 1793 if (idx + 1 >= sec->reloc_count) 1794 break; 1795 r = sec->orelocation[idx + 1]; 1796 if (r->address != ptr->address 1797 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section) 1798 || (*r->sym_ptr_ptr)->value != 0) 1799 break; 1800 1801 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */ 1802 1803 if (i == 0) 1804 int_rela.r_type2 = r->howto->type; 1805 else 1806 int_rela.r_type3 = r->howto->type; 1807 1808 ++idx; 1809 } 1810 1811 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela); 1812 } 1813 1814 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents 1815 == count); 1816 } 1817 1818 /* Irix 6 defines a brand new archive map format, so that they can 1819 have archives more than 4 GB in size. */ 1820 1821 /* Read an Irix 6 armap. */ 1822 1823 static boolean 1824 mips_elf64_slurp_armap (abfd) 1825 bfd *abfd; 1826 { 1827 struct artdata *ardata = bfd_ardata (abfd); 1828 char nextname[17]; 1829 file_ptr arhdrpos; 1830 bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize; 1831 struct areltdata *mapdata; 1832 bfd_byte int_buf[8]; 1833 char *stringbase; 1834 bfd_byte *raw_armap = NULL; 1835 carsym *carsyms; 1836 1837 ardata->symdefs = NULL; 1838 1839 /* Get the name of the first element. */ 1840 arhdrpos = bfd_tell (abfd); 1841 i = bfd_read ((PTR) nextname, 1, 16, abfd); 1842 if (i == 0) 1843 return true; 1844 if (i != 16) 1845 return false; 1846 1847 if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) 1848 return false; 1849 1850 /* Archives with traditional armaps are still permitted. */ 1851 if (strncmp (nextname, "/ ", 16) == 0) 1852 return bfd_slurp_armap (abfd); 1853 1854 if (strncmp (nextname, "/SYM64/ ", 16) != 0) 1855 { 1856 bfd_has_map (abfd) = false; 1857 return true; 1858 } 1859 1860 mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); 1861 if (mapdata == NULL) 1862 return false; 1863 parsed_size = mapdata->parsed_size; 1864 bfd_release (abfd, (PTR) mapdata); 1865 1866 if (bfd_read (int_buf, 1, 8, abfd) != 8) 1867 { 1868 if (bfd_get_error () != bfd_error_system_call) 1869 bfd_set_error (bfd_error_malformed_archive); 1870 return false; 1871 } 1872 1873 nsymz = bfd_getb64 (int_buf); 1874 stringsize = parsed_size - 8 * nsymz - 8; 1875 1876 carsym_size = nsymz * sizeof (carsym); 1877 ptrsize = 8 * nsymz; 1878 1879 ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1); 1880 if (ardata->symdefs == NULL) 1881 return false; 1882 carsyms = ardata->symdefs; 1883 stringbase = ((char *) ardata->symdefs) + carsym_size; 1884 1885 raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize); 1886 if (raw_armap == NULL) 1887 goto error_return; 1888 1889 if (bfd_read (raw_armap, 1, ptrsize, abfd) != ptrsize 1890 || bfd_read (stringbase, 1, stringsize, abfd) != stringsize) 1891 { 1892 if (bfd_get_error () != bfd_error_system_call) 1893 bfd_set_error (bfd_error_malformed_archive); 1894 goto error_return; 1895 } 1896 1897 for (i = 0; i < nsymz; i++) 1898 { 1899 carsyms->file_offset = bfd_getb64 (raw_armap + i * 8); 1900 carsyms->name = stringbase; 1901 stringbase += strlen (stringbase) + 1; 1902 ++carsyms; 1903 } 1904 *stringbase = '\0'; 1905 1906 ardata->symdef_count = nsymz; 1907 ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size; 1908 1909 bfd_has_map (abfd) = true; 1910 bfd_release (abfd, raw_armap); 1911 1912 return true; 1913 1914 error_return: 1915 if (raw_armap != NULL) 1916 bfd_release (abfd, raw_armap); 1917 if (ardata->symdefs != NULL) 1918 bfd_release (abfd, ardata->symdefs); 1919 return false; 1920 } 1921 1922 /* Write out an Irix 6 armap. The Irix 6 tools are supposed to be 1923 able to handle ordinary ELF armaps, but at least on Irix 6.2 the 1924 linker crashes. */ 1925 1926 static boolean 1927 mips_elf64_write_armap (arch, elength, map, symbol_count, stridx) 1928 bfd *arch; 1929 unsigned int elength; 1930 struct orl *map; 1931 unsigned int symbol_count; 1932 int stridx; 1933 { 1934 unsigned int ranlibsize = (symbol_count * 8) + 8; 1935 unsigned int stringsize = stridx; 1936 unsigned int mapsize = stringsize + ranlibsize; 1937 file_ptr archive_member_file_ptr; 1938 bfd *current = arch->archive_head; 1939 unsigned int count; 1940 struct ar_hdr hdr; 1941 unsigned int i; 1942 int padding; 1943 bfd_byte buf[8]; 1944 1945 padding = BFD_ALIGN (mapsize, 8) - mapsize; 1946 mapsize += padding; 1947 1948 /* work out where the first object file will go in the archive */ 1949 archive_member_file_ptr = (mapsize 1950 + elength 1951 + sizeof (struct ar_hdr) 1952 + SARMAG); 1953 1954 memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); 1955 strcpy (hdr.ar_name, "/SYM64/"); 1956 sprintf (hdr.ar_size, "%-10d", (int) mapsize); 1957 sprintf (hdr.ar_date, "%ld", (long) time (NULL)); 1958 /* This, at least, is what Intel coff sets the values to.: */ 1959 sprintf ((hdr.ar_uid), "%d", 0); 1960 sprintf ((hdr.ar_gid), "%d", 0); 1961 sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); 1962 strncpy (hdr.ar_fmag, ARFMAG, 2); 1963 1964 for (i = 0; i < sizeof (struct ar_hdr); i++) 1965 if (((char *) (&hdr))[i] == '\0') 1966 (((char *) (&hdr))[i]) = ' '; 1967 1968 /* Write the ar header for this item and the number of symbols */ 1969 1970 if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch) 1971 != sizeof (struct ar_hdr)) 1972 return false; 1973 1974 bfd_putb64 (symbol_count, buf); 1975 if (bfd_write (buf, 1, 8, arch) != 8) 1976 return false; 1977 1978 /* Two passes, first write the file offsets for each symbol - 1979 remembering that each offset is on a two byte boundary. */ 1980 1981 /* Write out the file offset for the file associated with each 1982 symbol, and remember to keep the offsets padded out. */ 1983 1984 current = arch->archive_head; 1985 count = 0; 1986 while (current != (bfd *) NULL && count < symbol_count) 1987 { 1988 /* For each symbol which is used defined in this object, write out 1989 the object file's address in the archive */ 1990 1991 while (((bfd *) (map[count]).pos) == current) 1992 { 1993 bfd_putb64 (archive_member_file_ptr, buf); 1994 if (bfd_write (buf, 1, 8, arch) != 8) 1995 return false; 1996 count++; 1997 } 1998 /* Add size of this archive entry */ 1999 archive_member_file_ptr += (arelt_size (current) 2000 + sizeof (struct ar_hdr)); 2001 /* remember about the even alignment */ 2002 archive_member_file_ptr += archive_member_file_ptr % 2; 2003 current = current->next; 2004 } 2005 2006 /* now write the strings themselves */ 2007 for (count = 0; count < symbol_count; count++) 2008 { 2009 size_t len = strlen (*map[count].name) + 1; 2010 2011 if (bfd_write (*map[count].name, 1, len, arch) != len) 2012 return false; 2013 } 2014 2015 /* The spec says that this should be padded to an 8 byte boundary. 2016 However, the Irix 6.2 tools do not appear to do this. */ 2017 while (padding != 0) 2018 { 2019 if (bfd_write ("", 1, 1, arch) != 1) 2020 return false; 2021 --padding; 2022 } 2023 2024 return true; 2025 } 2026 2027 /* ECOFF swapping routines. These are used when dealing with the 2028 .mdebug section, which is in the ECOFF debugging format. */ 2029 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap = 2030 { 2031 /* Symbol table magic number. */ 2032 magicSym2, 2033 /* Alignment of debugging information. E.g., 4. */ 2034 8, 2035 /* Sizes of external symbolic information. */ 2036 sizeof (struct hdr_ext), 2037 sizeof (struct dnr_ext), 2038 sizeof (struct pdr_ext), 2039 sizeof (struct sym_ext), 2040 sizeof (struct opt_ext), 2041 sizeof (struct fdr_ext), 2042 sizeof (struct rfd_ext), 2043 sizeof (struct ext_ext), 2044 /* Functions to swap in external symbolic data. */ 2045 ecoff_swap_hdr_in, 2046 ecoff_swap_dnr_in, 2047 ecoff_swap_pdr_in, 2048 ecoff_swap_sym_in, 2049 ecoff_swap_opt_in, 2050 ecoff_swap_fdr_in, 2051 ecoff_swap_rfd_in, 2052 ecoff_swap_ext_in, 2053 _bfd_ecoff_swap_tir_in, 2054 _bfd_ecoff_swap_rndx_in, 2055 /* Functions to swap out external symbolic data. */ 2056 ecoff_swap_hdr_out, 2057 ecoff_swap_dnr_out, 2058 ecoff_swap_pdr_out, 2059 ecoff_swap_sym_out, 2060 ecoff_swap_opt_out, 2061 ecoff_swap_fdr_out, 2062 ecoff_swap_rfd_out, 2063 ecoff_swap_ext_out, 2064 _bfd_ecoff_swap_tir_out, 2065 _bfd_ecoff_swap_rndx_out, 2066 /* Function to read in symbolic data. */ 2067 _bfd_mips_elf_read_ecoff_info 2068 }; 2069 2070 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in 2071 standard ELF. This structure is used to redirect the relocation 2072 handling routines. */ 2073 2074 const struct elf_size_info mips_elf64_size_info = 2075 { 2076 sizeof (Elf64_External_Ehdr), 2077 sizeof (Elf64_External_Phdr), 2078 sizeof (Elf64_External_Shdr), 2079 sizeof (Elf64_Mips_External_Rel), 2080 sizeof (Elf64_Mips_External_Rela), 2081 sizeof (Elf64_External_Sym), 2082 sizeof (Elf64_External_Dyn), 2083 sizeof (Elf_External_Note), 2084 4, /* hash-table entry size */ 2085 3, /* internal relocations per external relocations */ 2086 64, /* arch_size */ 2087 8, /* file_align */ 2088 ELFCLASS64, 2089 EV_CURRENT, 2090 bfd_elf64_write_out_phdrs, 2091 bfd_elf64_write_shdrs_and_ehdr, 2092 mips_elf64_write_relocs, 2093 bfd_elf64_swap_symbol_out, 2094 mips_elf64_slurp_reloc_table, 2095 bfd_elf64_slurp_symbol_table, 2096 bfd_elf64_swap_dyn_in, 2097 bfd_elf64_swap_dyn_out, 2098 mips_elf64_be_swap_reloc_in, 2099 mips_elf64_be_swap_reloc_out, 2100 mips_elf64_be_swap_reloca_in, 2101 mips_elf64_be_swap_reloca_out 2102 }; 2103 2104 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec 2105 #define TARGET_LITTLE_NAME "elf64-littlemips" 2106 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec 2107 #define TARGET_BIG_NAME "elf64-bigmips" 2108 #define ELF_ARCH bfd_arch_mips 2109 #define ELF_MACHINE_CODE EM_MIPS 2110 2111 #define ELF_MAXPAGESIZE 0x1000 2112 2113 #define elf_backend_collect true 2114 #define elf_backend_type_change_ok true 2115 #define elf_backend_can_gc_sections true 2116 #define elf_backend_size_info mips_elf64_size_info 2117 #define elf_backend_object_p _bfd_mips_elf_object_p 2118 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr 2119 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections 2120 #define elf_backend_section_from_bfd_section \ 2121 _bfd_mips_elf_section_from_bfd_section 2122 #define elf_backend_section_processing _bfd_mips_elf_section_processing 2123 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing 2124 #define elf_backend_additional_program_headers \ 2125 _bfd_mips_elf_additional_program_headers 2126 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map 2127 #define elf_backend_final_write_processing \ 2128 _bfd_mips_elf_final_write_processing 2129 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap 2130 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook 2131 #define elf_backend_create_dynamic_sections \ 2132 _bfd_mips_elf_create_dynamic_sections 2133 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs 2134 #define elf_backend_adjust_dynamic_symbol \ 2135 _bfd_mips_elf_adjust_dynamic_symbol 2136 #define elf_backend_always_size_sections \ 2137 _bfd_mips_elf_always_size_sections 2138 #define elf_backend_size_dynamic_sections \ 2139 _bfd_mips_elf_size_dynamic_sections 2140 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section 2141 #define elf_backend_link_output_symbol_hook \ 2142 _bfd_mips_elf_link_output_symbol_hook 2143 #define elf_backend_finish_dynamic_symbol \ 2144 _bfd_mips_elf_finish_dynamic_symbol 2145 #define elf_backend_finish_dynamic_sections \ 2146 _bfd_mips_elf_finish_dynamic_sections 2147 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook 2148 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook 2149 #define elf_backend_got_header_size (4*MIPS_RESERVED_GOTNO) 2150 #define elf_backend_plt_header_size 0 2151 #define elf_backend_may_use_rel_p 1 2152 2153 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit 2154 MIPS-specific function only applies to IRIX5, which had no 64-bit 2155 ABI. */ 2156 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line 2157 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents 2158 #define bfd_elf64_bfd_link_hash_table_create \ 2159 _bfd_mips_elf_link_hash_table_create 2160 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link 2161 #define bfd_elf64_bfd_copy_private_bfd_data \ 2162 _bfd_mips_elf_copy_private_bfd_data 2163 #define bfd_elf64_bfd_merge_private_bfd_data \ 2164 _bfd_mips_elf_merge_private_bfd_data 2165 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags 2166 #define bfd_elf64_bfd_print_private_bfd_data \ 2167 _bfd_mips_elf_print_private_bfd_data 2168 2169 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound 2170 #define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup 2171 #define bfd_elf64_archive_functions 2172 #define bfd_elf64_archive_slurp_armap mips_elf64_slurp_armap 2173 #define bfd_elf64_archive_slurp_extended_name_table \ 2174 _bfd_archive_coff_slurp_extended_name_table 2175 #define bfd_elf64_archive_construct_extended_name_table \ 2176 _bfd_archive_coff_construct_extended_name_table 2177 #define bfd_elf64_archive_truncate_arname \ 2178 _bfd_archive_coff_truncate_arname 2179 #define bfd_elf64_archive_write_armap mips_elf64_write_armap 2180 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr 2181 #define bfd_elf64_archive_openr_next_archived_file \ 2182 _bfd_archive_coff_openr_next_archived_file 2183 #define bfd_elf64_archive_get_elt_at_index \ 2184 _bfd_archive_coff_get_elt_at_index 2185 #define bfd_elf64_archive_generic_stat_arch_elt \ 2186 _bfd_archive_coff_generic_stat_arch_elt 2187 #define bfd_elf64_archive_update_armap_timestamp \ 2188 _bfd_archive_coff_update_armap_timestamp 2189 2190 #include "elf64-target.h" 2191