1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Ian Lance Taylor, Cygnus Support
5 Linker support added by Mark Mitchell, CodeSourcery, LLC.
6 <mark@codesourcery.com>
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 /* This file supports the 64-bit MIPS ELF ABI.
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. */
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).
33 . - Relocation handling for REL relocs is wrong in many cases and
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.
50 #include "elfxx-mips.h"
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. */
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"
64 static void mips_elf64_swap_reloc_in
65 PARAMS ((bfd
*, const Elf64_Mips_External_Rel
*,
66 Elf64_Mips_Internal_Rela
*));
67 static void mips_elf64_swap_reloca_in
68 PARAMS ((bfd
*, const Elf64_Mips_External_Rela
*,
69 Elf64_Mips_Internal_Rela
*));
70 static void mips_elf64_swap_reloc_out
71 PARAMS ((bfd
*, const Elf64_Mips_Internal_Rela
*,
72 Elf64_Mips_External_Rel
*));
73 static void mips_elf64_swap_reloca_out
74 PARAMS ((bfd
*, const Elf64_Mips_Internal_Rela
*,
75 Elf64_Mips_External_Rela
*));
76 static void mips_elf64_be_swap_reloc_in
77 PARAMS ((bfd
*, const bfd_byte
*, Elf_Internal_Rela
*));
78 static void mips_elf64_be_swap_reloc_out
79 PARAMS ((bfd
*, const Elf_Internal_Rela
*, bfd_byte
*));
80 static void mips_elf64_be_swap_reloca_in
81 PARAMS ((bfd
*, const bfd_byte
*, Elf_Internal_Rela
*));
82 static void mips_elf64_be_swap_reloca_out
83 PARAMS ((bfd
*, const Elf_Internal_Rela
*, bfd_byte
*));
84 static reloc_howto_type
*bfd_elf64_bfd_reloc_type_lookup
85 PARAMS ((bfd
*, bfd_reloc_code_real_type
));
86 static reloc_howto_type
*mips_elf64_rtype_to_howto
87 PARAMS ((unsigned int, bfd_boolean
));
88 static void mips_elf64_info_to_howto_rel
89 PARAMS ((bfd
*, arelent
*, Elf_Internal_Rela
*));
90 static void mips_elf64_info_to_howto_rela
91 PARAMS ((bfd
*, arelent
*, Elf_Internal_Rela
*));
92 static long mips_elf64_get_reloc_upper_bound
93 PARAMS ((bfd
*, asection
*));
94 static bfd_boolean mips_elf64_slurp_one_reloc_table
95 PARAMS ((bfd
*, asection
*, asymbol
**, const Elf_Internal_Shdr
*));
96 static bfd_boolean mips_elf64_slurp_reloc_table
97 PARAMS ((bfd
*, asection
*, asymbol
**, bfd_boolean
));
98 static void mips_elf64_write_relocs
99 PARAMS ((bfd
*, asection
*, PTR
));
100 static void mips_elf64_write_rel
101 PARAMS((bfd
*, asection
*, Elf_Internal_Shdr
*, int *, PTR
));
102 static void mips_elf64_write_rela
103 PARAMS((bfd
*, asection
*, Elf_Internal_Shdr
*, int *, PTR
));
104 static bfd_reloc_status_type mips_elf64_hi16_reloc
105 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
106 static bfd_reloc_status_type mips_elf64_gprel16_reloc
107 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
108 static bfd_reloc_status_type mips_elf64_literal_reloc
109 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
110 static bfd_reloc_status_type mips_elf64_gprel32_reloc
111 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
112 static bfd_reloc_status_type mips_elf64_shift6_reloc
113 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
114 static bfd_reloc_status_type mips_elf64_got16_reloc
115 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
116 static bfd_reloc_status_type mips16_jump_reloc
117 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
118 static bfd_reloc_status_type mips16_gprel_reloc
119 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
120 static bfd_boolean mips_elf64_assign_gp
121 PARAMS ((bfd
*, bfd_vma
*));
122 static bfd_reloc_status_type mips_elf64_final_gp
123 PARAMS ((bfd
*, asymbol
*, bfd_boolean
, char **, bfd_vma
*));
124 static bfd_boolean mips_elf64_object_p
126 static irix_compat_t elf64_mips_irix_compat
128 static bfd_boolean elf64_mips_grok_prstatus
129 PARAMS ((bfd
*, Elf_Internal_Note
*));
130 static bfd_boolean elf64_mips_grok_psinfo
131 PARAMS ((bfd
*, Elf_Internal_Note
*));
133 extern const bfd_target bfd_elf64_bigmips_vec
;
134 extern const bfd_target bfd_elf64_littlemips_vec
;
136 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
137 from smaller values. Start with zero, widen, *then* decrement. */
138 #define MINUS_ONE (((bfd_vma)0) - 1)
140 /* The number of local .got entries we reserve. */
141 #define MIPS_RESERVED_GOTNO (2)
143 /* The relocation table used for SHT_REL sections. */
145 static reloc_howto_type mips_elf64_howto_table_rel
[] =
148 HOWTO (R_MIPS_NONE
, /* type */
150 0, /* size (0 = byte, 1 = short, 2 = long) */
152 FALSE
, /* pc_relative */
154 complain_overflow_dont
, /* complain_on_overflow */
155 bfd_elf_generic_reloc
, /* special_function */
156 "R_MIPS_NONE", /* name */
157 FALSE
, /* partial_inplace */
160 FALSE
), /* pcrel_offset */
162 /* 16 bit relocation. */
163 HOWTO (R_MIPS_16
, /* type */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
167 FALSE
, /* pc_relative */
169 complain_overflow_signed
, /* complain_on_overflow */
170 bfd_elf_generic_reloc
, /* special_function */
171 "R_MIPS_16", /* name */
172 TRUE
, /* partial_inplace */
173 0x0000ffff, /* src_mask */
174 0x0000ffff, /* dst_mask */
175 FALSE
), /* pcrel_offset */
177 /* 32 bit relocation. */
178 HOWTO (R_MIPS_32
, /* type */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
182 FALSE
, /* pc_relative */
184 complain_overflow_dont
, /* complain_on_overflow */
185 bfd_elf_generic_reloc
, /* special_function */
186 "R_MIPS_32", /* name */
187 TRUE
, /* partial_inplace */
188 0xffffffff, /* src_mask */
189 0xffffffff, /* dst_mask */
190 FALSE
), /* pcrel_offset */
192 /* 32 bit symbol relative relocation. */
193 HOWTO (R_MIPS_REL32
, /* type */
195 2, /* size (0 = byte, 1 = short, 2 = long) */
197 FALSE
, /* pc_relative */
199 complain_overflow_dont
, /* complain_on_overflow */
200 bfd_elf_generic_reloc
, /* special_function */
201 "R_MIPS_REL32", /* name */
202 TRUE
, /* partial_inplace */
203 0xffffffff, /* src_mask */
204 0xffffffff, /* dst_mask */
205 FALSE
), /* pcrel_offset */
207 /* 26 bit jump address. */
208 HOWTO (R_MIPS_26
, /* type */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
212 FALSE
, /* pc_relative */
214 complain_overflow_dont
, /* complain_on_overflow */
215 /* This needs complex overflow
216 detection, because the upper 36
217 bits must match the PC + 4. */
218 bfd_elf_generic_reloc
, /* special_function */
219 "R_MIPS_26", /* name */
220 TRUE
, /* partial_inplace */
221 0x03ffffff, /* src_mask */
222 0x03ffffff, /* dst_mask */
223 FALSE
), /* pcrel_offset */
225 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
226 However, the native IRIX6 tools use them, so we try our best. */
228 /* High 16 bits of symbol value. */
229 HOWTO (R_MIPS_HI16
, /* type */
231 2, /* size (0 = byte, 1 = short, 2 = long) */
233 FALSE
, /* pc_relative */
235 complain_overflow_dont
, /* complain_on_overflow */
236 mips_elf64_hi16_reloc
, /* special_function */
237 "R_MIPS_HI16", /* name */
238 TRUE
, /* partial_inplace */
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
241 FALSE
), /* pcrel_offset */
243 /* Low 16 bits of symbol value. */
244 HOWTO (R_MIPS_LO16
, /* type */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
248 FALSE
, /* pc_relative */
250 complain_overflow_dont
, /* complain_on_overflow */
251 bfd_elf_generic_reloc
, /* special_function */
252 "R_MIPS_LO16", /* name */
253 TRUE
, /* partial_inplace */
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
256 FALSE
), /* pcrel_offset */
258 /* GP relative reference. */
259 HOWTO (R_MIPS_GPREL16
, /* type */
261 2, /* size (0 = byte, 1 = short, 2 = long) */
263 FALSE
, /* pc_relative */
265 complain_overflow_signed
, /* complain_on_overflow */
266 mips_elf64_gprel16_reloc
, /* special_function */
267 "R_MIPS_GPREL16", /* name */
268 TRUE
, /* partial_inplace */
269 0x0000ffff, /* src_mask */
270 0x0000ffff, /* dst_mask */
271 FALSE
), /* pcrel_offset */
273 /* Reference to literal section. */
274 HOWTO (R_MIPS_LITERAL
, /* type */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
278 FALSE
, /* pc_relative */
280 complain_overflow_signed
, /* complain_on_overflow */
281 mips_elf64_literal_reloc
, /* special_function */
282 "R_MIPS_LITERAL", /* name */
283 TRUE
, /* partial_inplace */
284 0x0000ffff, /* src_mask */
285 0x0000ffff, /* dst_mask */
286 FALSE
), /* pcrel_offset */
288 /* Reference to global offset table. */
289 HOWTO (R_MIPS_GOT16
, /* type */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
293 FALSE
, /* pc_relative */
295 complain_overflow_signed
, /* complain_on_overflow */
296 mips_elf64_got16_reloc
, /* special_function */
297 "R_MIPS_GOT16", /* name */
298 TRUE
, /* partial_inplace */
299 0x0000ffff, /* src_mask */
300 0x0000ffff, /* dst_mask */
301 FALSE
), /* pcrel_offset */
303 /* 16 bit PC relative reference. Note that the ABI document has a typo
304 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
305 We do the right thing here. */
306 HOWTO (R_MIPS_PC16
, /* type */
308 2, /* size (0 = byte, 1 = short, 2 = long) */
310 TRUE
, /* pc_relative */
312 complain_overflow_signed
, /* complain_on_overflow */
313 bfd_elf_generic_reloc
, /* special_function */
314 "R_MIPS_PC16", /* name */
315 TRUE
, /* partial_inplace */
316 0x0000ffff, /* src_mask */
317 0x0000ffff, /* dst_mask */
318 TRUE
), /* pcrel_offset */
320 /* 16 bit call through global offset table. */
321 HOWTO (R_MIPS_CALL16
, /* type */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
325 FALSE
, /* pc_relative */
327 complain_overflow_signed
, /* complain_on_overflow */
328 bfd_elf_generic_reloc
, /* special_function */
329 "R_MIPS_CALL16", /* name */
330 TRUE
, /* partial_inplace */
331 0x0000ffff, /* src_mask */
332 0x0000ffff, /* dst_mask */
333 FALSE
), /* pcrel_offset */
335 /* 32 bit GP relative reference. */
336 HOWTO (R_MIPS_GPREL32
, /* type */
338 2, /* size (0 = byte, 1 = short, 2 = long) */
340 FALSE
, /* pc_relative */
342 complain_overflow_dont
, /* complain_on_overflow */
343 mips_elf64_gprel32_reloc
, /* special_function */
344 "R_MIPS_GPREL32", /* name */
345 TRUE
, /* partial_inplace */
346 0xffffffff, /* src_mask */
347 0xffffffff, /* dst_mask */
348 FALSE
), /* pcrel_offset */
354 /* A 5 bit shift field. */
355 HOWTO (R_MIPS_SHIFT5
, /* type */
357 2, /* size (0 = byte, 1 = short, 2 = long) */
359 FALSE
, /* pc_relative */
361 complain_overflow_bitfield
, /* complain_on_overflow */
362 bfd_elf_generic_reloc
, /* special_function */
363 "R_MIPS_SHIFT5", /* name */
364 TRUE
, /* partial_inplace */
365 0x000007c0, /* src_mask */
366 0x000007c0, /* dst_mask */
367 FALSE
), /* pcrel_offset */
369 /* A 6 bit shift field. */
370 HOWTO (R_MIPS_SHIFT6
, /* type */
372 2, /* size (0 = byte, 1 = short, 2 = long) */
374 FALSE
, /* pc_relative */
376 complain_overflow_bitfield
, /* complain_on_overflow */
377 mips_elf64_shift6_reloc
, /* special_function */
378 "R_MIPS_SHIFT6", /* name */
379 TRUE
, /* partial_inplace */
380 0x000007c4, /* src_mask */
381 0x000007c4, /* dst_mask */
382 FALSE
), /* pcrel_offset */
384 /* 64 bit relocation. */
385 HOWTO (R_MIPS_64
, /* type */
387 4, /* size (0 = byte, 1 = short, 2 = long) */
389 FALSE
, /* pc_relative */
391 complain_overflow_dont
, /* complain_on_overflow */
392 bfd_elf_generic_reloc
, /* special_function */
393 "R_MIPS_64", /* name */
394 TRUE
, /* partial_inplace */
395 MINUS_ONE
, /* src_mask */
396 MINUS_ONE
, /* dst_mask */
397 FALSE
), /* pcrel_offset */
399 /* Displacement in the global offset table. */
400 HOWTO (R_MIPS_GOT_DISP
, /* type */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
404 FALSE
, /* pc_relative */
406 complain_overflow_signed
, /* complain_on_overflow */
407 bfd_elf_generic_reloc
, /* special_function */
408 "R_MIPS_GOT_DISP", /* name */
409 TRUE
, /* partial_inplace */
410 0x0000ffff, /* src_mask */
411 0x0000ffff, /* dst_mask */
412 FALSE
), /* pcrel_offset */
414 /* Displacement to page pointer in the global offset table. */
415 HOWTO (R_MIPS_GOT_PAGE
, /* type */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
419 FALSE
, /* pc_relative */
421 complain_overflow_signed
, /* complain_on_overflow */
422 bfd_elf_generic_reloc
, /* special_function */
423 "R_MIPS_GOT_PAGE", /* name */
424 TRUE
, /* partial_inplace */
425 0x0000ffff, /* src_mask */
426 0x0000ffff, /* dst_mask */
427 FALSE
), /* pcrel_offset */
429 /* Offset from page pointer in the global offset table. */
430 HOWTO (R_MIPS_GOT_OFST
, /* type */
432 2, /* size (0 = byte, 1 = short, 2 = long) */
434 FALSE
, /* pc_relative */
436 complain_overflow_signed
, /* complain_on_overflow */
437 bfd_elf_generic_reloc
, /* special_function */
438 "R_MIPS_GOT_OFST", /* name */
439 TRUE
, /* partial_inplace */
440 0x0000ffff, /* src_mask */
441 0x0000ffff, /* dst_mask */
442 FALSE
), /* pcrel_offset */
444 /* High 16 bits of displacement in global offset table. */
445 HOWTO (R_MIPS_GOT_HI16
, /* type */
447 2, /* size (0 = byte, 1 = short, 2 = long) */
449 FALSE
, /* pc_relative */
451 complain_overflow_dont
, /* complain_on_overflow */
452 bfd_elf_generic_reloc
, /* special_function */
453 "R_MIPS_GOT_HI16", /* name */
454 TRUE
, /* partial_inplace */
455 0x0000ffff, /* src_mask */
456 0x0000ffff, /* dst_mask */
457 FALSE
), /* pcrel_offset */
459 /* Low 16 bits of displacement in global offset table. */
460 HOWTO (R_MIPS_GOT_LO16
, /* type */
462 2, /* size (0 = byte, 1 = short, 2 = long) */
464 FALSE
, /* pc_relative */
466 complain_overflow_dont
, /* complain_on_overflow */
467 bfd_elf_generic_reloc
, /* special_function */
468 "R_MIPS_GOT_LO16", /* name */
469 TRUE
, /* partial_inplace */
470 0x0000ffff, /* src_mask */
471 0x0000ffff, /* dst_mask */
472 FALSE
), /* pcrel_offset */
474 /* 64 bit substraction. */
475 HOWTO (R_MIPS_SUB
, /* type */
477 4, /* size (0 = byte, 1 = short, 2 = long) */
479 FALSE
, /* pc_relative */
481 complain_overflow_dont
, /* complain_on_overflow */
482 bfd_elf_generic_reloc
, /* special_function */
483 "R_MIPS_SUB", /* name */
484 TRUE
, /* partial_inplace */
485 MINUS_ONE
, /* src_mask */
486 MINUS_ONE
, /* dst_mask */
487 FALSE
), /* pcrel_offset */
489 /* Insert the addend as an instruction. */
490 /* FIXME: Not handled correctly. */
491 HOWTO (R_MIPS_INSERT_A
, /* type */
493 2, /* size (0 = byte, 1 = short, 2 = long) */
495 FALSE
, /* pc_relative */
497 complain_overflow_dont
, /* complain_on_overflow */
498 bfd_elf_generic_reloc
, /* special_function */
499 "R_MIPS_INSERT_A", /* name */
500 TRUE
, /* partial_inplace */
501 0xffffffff, /* src_mask */
502 0xffffffff, /* dst_mask */
503 FALSE
), /* pcrel_offset */
505 /* Insert the addend as an instruction, and change all relocations
506 to refer to the old instruction at the address. */
507 /* FIXME: Not handled correctly. */
508 HOWTO (R_MIPS_INSERT_B
, /* type */
510 2, /* size (0 = byte, 1 = short, 2 = long) */
512 FALSE
, /* pc_relative */
514 complain_overflow_dont
, /* complain_on_overflow */
515 bfd_elf_generic_reloc
, /* special_function */
516 "R_MIPS_INSERT_B", /* name */
517 TRUE
, /* partial_inplace */
518 0xffffffff, /* src_mask */
519 0xffffffff, /* dst_mask */
520 FALSE
), /* pcrel_offset */
522 /* Delete a 32 bit instruction. */
523 /* FIXME: Not handled correctly. */
524 HOWTO (R_MIPS_DELETE
, /* type */
526 2, /* size (0 = byte, 1 = short, 2 = long) */
528 FALSE
, /* pc_relative */
530 complain_overflow_dont
, /* complain_on_overflow */
531 bfd_elf_generic_reloc
, /* special_function */
532 "R_MIPS_DELETE", /* name */
533 TRUE
, /* partial_inplace */
534 0xffffffff, /* src_mask */
535 0xffffffff, /* dst_mask */
536 FALSE
), /* pcrel_offset */
538 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
540 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
541 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
543 b) No other NewABI toolchain actually emits such relocations. */
544 EMPTY_HOWTO (R_MIPS_HIGHER
),
545 EMPTY_HOWTO (R_MIPS_HIGHEST
),
547 /* High 16 bits of displacement in global offset table. */
548 HOWTO (R_MIPS_CALL_HI16
, /* type */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
552 FALSE
, /* pc_relative */
554 complain_overflow_dont
, /* complain_on_overflow */
555 bfd_elf_generic_reloc
, /* special_function */
556 "R_MIPS_CALL_HI16", /* name */
557 TRUE
, /* partial_inplace */
558 0x0000ffff, /* src_mask */
559 0x0000ffff, /* dst_mask */
560 FALSE
), /* pcrel_offset */
562 /* Low 16 bits of displacement in global offset table. */
563 HOWTO (R_MIPS_CALL_LO16
, /* type */
565 2, /* size (0 = byte, 1 = short, 2 = long) */
567 FALSE
, /* pc_relative */
569 complain_overflow_dont
, /* complain_on_overflow */
570 bfd_elf_generic_reloc
, /* special_function */
571 "R_MIPS_CALL_LO16", /* name */
572 TRUE
, /* partial_inplace */
573 0x0000ffff, /* src_mask */
574 0x0000ffff, /* dst_mask */
575 FALSE
), /* pcrel_offset */
577 /* Section displacement, used by an associated event location section. */
578 HOWTO (R_MIPS_SCN_DISP
, /* type */
580 2, /* size (0 = byte, 1 = short, 2 = long) */
582 FALSE
, /* pc_relative */
584 complain_overflow_dont
, /* complain_on_overflow */
585 bfd_elf_generic_reloc
, /* special_function */
586 "R_MIPS_SCN_DISP", /* name */
587 TRUE
, /* partial_inplace */
588 0xffffffff, /* src_mask */
589 0xffffffff, /* dst_mask */
590 FALSE
), /* pcrel_offset */
592 HOWTO (R_MIPS_REL16
, /* type */
594 1, /* size (0 = byte, 1 = short, 2 = long) */
596 FALSE
, /* pc_relative */
598 complain_overflow_signed
, /* complain_on_overflow */
599 bfd_elf_generic_reloc
, /* special_function */
600 "R_MIPS_REL16", /* name */
601 TRUE
, /* partial_inplace */
602 0xffff, /* src_mask */
603 0xffff, /* dst_mask */
604 FALSE
), /* pcrel_offset */
606 /* These two are obsolete. */
607 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
608 EMPTY_HOWTO (R_MIPS_PJUMP
),
610 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
611 It must be used for multigot GOT's (and only there). */
612 HOWTO (R_MIPS_RELGOT
, /* type */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
616 FALSE
, /* pc_relative */
618 complain_overflow_dont
, /* complain_on_overflow */
619 bfd_elf_generic_reloc
, /* special_function */
620 "R_MIPS_RELGOT", /* name */
621 TRUE
, /* partial_inplace */
622 0xffffffff, /* src_mask */
623 0xffffffff, /* dst_mask */
624 FALSE
), /* pcrel_offset */
626 /* Protected jump conversion. This is an optimization hint. No
627 relocation is required for correctness. */
628 HOWTO (R_MIPS_JALR
, /* type */
630 2, /* size (0 = byte, 1 = short, 2 = long) */
632 FALSE
, /* pc_relative */
634 complain_overflow_dont
, /* complain_on_overflow */
635 bfd_elf_generic_reloc
, /* special_function */
636 "R_MIPS_JALR", /* name */
637 FALSE
, /* partial_inplace */
639 0x00000000, /* dst_mask */
640 FALSE
), /* pcrel_offset */
643 /* The relocation table used for SHT_RELA sections. */
645 static reloc_howto_type mips_elf64_howto_table_rela
[] =
648 HOWTO (R_MIPS_NONE
, /* type */
650 0, /* size (0 = byte, 1 = short, 2 = long) */
652 FALSE
, /* pc_relative */
654 complain_overflow_dont
, /* complain_on_overflow */
655 bfd_elf_generic_reloc
, /* special_function */
656 "R_MIPS_NONE", /* name */
657 FALSE
, /* partial_inplace */
660 FALSE
), /* pcrel_offset */
662 /* 16 bit relocation. */
663 HOWTO (R_MIPS_16
, /* type */
665 2, /* size (0 = byte, 1 = short, 2 = long) */
667 FALSE
, /* pc_relative */
669 complain_overflow_signed
, /* complain_on_overflow */
670 bfd_elf_generic_reloc
, /* special_function */
671 "R_MIPS_16", /* name */
672 FALSE
, /* partial_inplace */
674 0x0000ffff, /* dst_mask */
675 FALSE
), /* pcrel_offset */
677 /* 32 bit relocation. */
678 HOWTO (R_MIPS_32
, /* type */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
682 FALSE
, /* pc_relative */
684 complain_overflow_dont
, /* complain_on_overflow */
685 bfd_elf_generic_reloc
, /* special_function */
686 "R_MIPS_32", /* name */
687 FALSE
, /* partial_inplace */
689 0xffffffff, /* dst_mask */
690 FALSE
), /* pcrel_offset */
692 /* 32 bit symbol relative relocation. */
693 HOWTO (R_MIPS_REL32
, /* type */
695 2, /* size (0 = byte, 1 = short, 2 = long) */
697 FALSE
, /* pc_relative */
699 complain_overflow_dont
, /* complain_on_overflow */
700 bfd_elf_generic_reloc
, /* special_function */
701 "R_MIPS_REL32", /* name */
702 FALSE
, /* partial_inplace */
704 0xffffffff, /* dst_mask */
705 FALSE
), /* pcrel_offset */
707 /* 26 bit jump address. */
708 HOWTO (R_MIPS_26
, /* type */
710 2, /* size (0 = byte, 1 = short, 2 = long) */
712 FALSE
, /* pc_relative */
714 complain_overflow_dont
, /* complain_on_overflow */
715 /* This needs complex overflow
716 detection, because the upper 36
717 bits must match the PC + 4. */
718 bfd_elf_generic_reloc
, /* special_function */
719 "R_MIPS_26", /* name */
720 FALSE
, /* partial_inplace */
722 0x03ffffff, /* dst_mask */
723 FALSE
), /* pcrel_offset */
725 /* High 16 bits of symbol value. */
726 HOWTO (R_MIPS_HI16
, /* type */
728 2, /* size (0 = byte, 1 = short, 2 = long) */
730 FALSE
, /* pc_relative */
732 complain_overflow_dont
, /* complain_on_overflow */
733 bfd_elf_generic_reloc
, /* special_function */
734 "R_MIPS_HI16", /* name */
735 FALSE
, /* partial_inplace */
737 0x0000ffff, /* dst_mask */
738 FALSE
), /* pcrel_offset */
740 /* Low 16 bits of symbol value. */
741 HOWTO (R_MIPS_LO16
, /* type */
743 2, /* size (0 = byte, 1 = short, 2 = long) */
745 FALSE
, /* pc_relative */
747 complain_overflow_dont
, /* complain_on_overflow */
748 bfd_elf_generic_reloc
, /* special_function */
749 "R_MIPS_LO16", /* name */
750 FALSE
, /* partial_inplace */
752 0x0000ffff, /* dst_mask */
753 FALSE
), /* pcrel_offset */
755 /* GP relative reference. */
756 HOWTO (R_MIPS_GPREL16
, /* type */
758 2, /* size (0 = byte, 1 = short, 2 = long) */
760 FALSE
, /* pc_relative */
762 complain_overflow_signed
, /* complain_on_overflow */
763 mips_elf64_gprel16_reloc
, /* special_function */
764 "R_MIPS_GPREL16", /* name */
765 FALSE
, /* partial_inplace */
767 0x0000ffff, /* dst_mask */
768 FALSE
), /* pcrel_offset */
770 /* Reference to literal section. */
771 HOWTO (R_MIPS_LITERAL
, /* type */
773 2, /* size (0 = byte, 1 = short, 2 = long) */
775 FALSE
, /* pc_relative */
777 complain_overflow_signed
, /* complain_on_overflow */
778 mips_elf64_literal_reloc
, /* special_function */
779 "R_MIPS_LITERAL", /* name */
780 FALSE
, /* partial_inplace */
782 0x0000ffff, /* dst_mask */
783 FALSE
), /* pcrel_offset */
785 /* Reference to global offset table. */
786 HOWTO (R_MIPS_GOT16
, /* type */
788 2, /* size (0 = byte, 1 = short, 2 = long) */
790 FALSE
, /* pc_relative */
792 complain_overflow_signed
, /* complain_on_overflow */
793 mips_elf64_got16_reloc
, /* special_function */
794 "R_MIPS_GOT16", /* name */
795 FALSE
, /* partial_inplace */
797 0x0000ffff, /* dst_mask */
798 FALSE
), /* pcrel_offset */
800 /* 16 bit PC relative reference. Note that the ABI document has a typo
801 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
802 We do the right thing here. */
803 HOWTO (R_MIPS_PC16
, /* type */
805 2, /* size (0 = byte, 1 = short, 2 = long) */
807 TRUE
, /* pc_relative */
809 complain_overflow_signed
, /* complain_on_overflow */
810 bfd_elf_generic_reloc
, /* special_function */
811 "R_MIPS_PC16", /* name */
812 FALSE
, /* partial_inplace */
814 0x0000ffff, /* dst_mask */
815 TRUE
), /* pcrel_offset */
817 /* 16 bit call through global offset table. */
818 HOWTO (R_MIPS_CALL16
, /* type */
820 2, /* size (0 = byte, 1 = short, 2 = long) */
822 FALSE
, /* pc_relative */
824 complain_overflow_signed
, /* complain_on_overflow */
825 bfd_elf_generic_reloc
, /* special_function */
826 "R_MIPS_CALL16", /* name */
827 FALSE
, /* partial_inplace */
829 0x0000ffff, /* dst_mask */
830 FALSE
), /* pcrel_offset */
832 /* 32 bit GP relative reference. */
833 HOWTO (R_MIPS_GPREL32
, /* type */
835 2, /* size (0 = byte, 1 = short, 2 = long) */
837 FALSE
, /* pc_relative */
839 complain_overflow_dont
, /* complain_on_overflow */
840 mips_elf64_gprel32_reloc
, /* special_function */
841 "R_MIPS_GPREL32", /* name */
842 FALSE
, /* partial_inplace */
844 0xffffffff, /* dst_mask */
845 FALSE
), /* pcrel_offset */
851 /* A 5 bit shift field. */
852 HOWTO (R_MIPS_SHIFT5
, /* type */
854 2, /* size (0 = byte, 1 = short, 2 = long) */
856 FALSE
, /* pc_relative */
858 complain_overflow_bitfield
, /* complain_on_overflow */
859 bfd_elf_generic_reloc
, /* special_function */
860 "R_MIPS_SHIFT5", /* name */
861 FALSE
, /* partial_inplace */
863 0x000007c0, /* dst_mask */
864 FALSE
), /* pcrel_offset */
866 /* A 6 bit shift field. */
867 HOWTO (R_MIPS_SHIFT6
, /* type */
869 2, /* size (0 = byte, 1 = short, 2 = long) */
871 FALSE
, /* pc_relative */
873 complain_overflow_bitfield
, /* complain_on_overflow */
874 mips_elf64_shift6_reloc
, /* special_function */
875 "R_MIPS_SHIFT6", /* name */
876 FALSE
, /* partial_inplace */
878 0x000007c4, /* dst_mask */
879 FALSE
), /* pcrel_offset */
881 /* 64 bit relocation. */
882 HOWTO (R_MIPS_64
, /* type */
884 4, /* size (0 = byte, 1 = short, 2 = long) */
886 FALSE
, /* pc_relative */
888 complain_overflow_dont
, /* complain_on_overflow */
889 bfd_elf_generic_reloc
, /* special_function */
890 "R_MIPS_64", /* name */
891 FALSE
, /* partial_inplace */
893 MINUS_ONE
, /* dst_mask */
894 FALSE
), /* pcrel_offset */
896 /* Displacement in the global offset table. */
897 HOWTO (R_MIPS_GOT_DISP
, /* type */
899 2, /* size (0 = byte, 1 = short, 2 = long) */
901 FALSE
, /* pc_relative */
903 complain_overflow_signed
, /* complain_on_overflow */
904 bfd_elf_generic_reloc
, /* special_function */
905 "R_MIPS_GOT_DISP", /* name */
906 FALSE
, /* partial_inplace */
908 0x0000ffff, /* dst_mask */
909 FALSE
), /* pcrel_offset */
911 /* Displacement to page pointer in the global offset table. */
912 HOWTO (R_MIPS_GOT_PAGE
, /* type */
914 2, /* size (0 = byte, 1 = short, 2 = long) */
916 FALSE
, /* pc_relative */
918 complain_overflow_signed
, /* complain_on_overflow */
919 bfd_elf_generic_reloc
, /* special_function */
920 "R_MIPS_GOT_PAGE", /* name */
921 FALSE
, /* partial_inplace */
923 0x0000ffff, /* dst_mask */
924 FALSE
), /* pcrel_offset */
926 /* Offset from page pointer in the global offset table. */
927 HOWTO (R_MIPS_GOT_OFST
, /* type */
929 2, /* size (0 = byte, 1 = short, 2 = long) */
931 FALSE
, /* pc_relative */
933 complain_overflow_signed
, /* complain_on_overflow */
934 bfd_elf_generic_reloc
, /* special_function */
935 "R_MIPS_GOT_OFST", /* name */
936 FALSE
, /* partial_inplace */
938 0x0000ffff, /* dst_mask */
939 FALSE
), /* pcrel_offset */
941 /* High 16 bits of displacement in global offset table. */
942 HOWTO (R_MIPS_GOT_HI16
, /* type */
944 2, /* size (0 = byte, 1 = short, 2 = long) */
946 FALSE
, /* pc_relative */
948 complain_overflow_dont
, /* complain_on_overflow */
949 bfd_elf_generic_reloc
, /* special_function */
950 "R_MIPS_GOT_HI16", /* name */
951 FALSE
, /* partial_inplace */
953 0x0000ffff, /* dst_mask */
954 FALSE
), /* pcrel_offset */
956 /* Low 16 bits of displacement in global offset table. */
957 HOWTO (R_MIPS_GOT_LO16
, /* type */
959 2, /* size (0 = byte, 1 = short, 2 = long) */
961 FALSE
, /* pc_relative */
963 complain_overflow_dont
, /* complain_on_overflow */
964 bfd_elf_generic_reloc
, /* special_function */
965 "R_MIPS_GOT_LO16", /* name */
966 FALSE
, /* partial_inplace */
968 0x0000ffff, /* dst_mask */
969 FALSE
), /* pcrel_offset */
971 /* 64 bit substraction. */
972 HOWTO (R_MIPS_SUB
, /* type */
974 4, /* size (0 = byte, 1 = short, 2 = long) */
976 FALSE
, /* pc_relative */
978 complain_overflow_dont
, /* complain_on_overflow */
979 bfd_elf_generic_reloc
, /* special_function */
980 "R_MIPS_SUB", /* name */
981 FALSE
, /* partial_inplace */
983 MINUS_ONE
, /* dst_mask */
984 FALSE
), /* pcrel_offset */
986 /* Insert the addend as an instruction. */
987 /* FIXME: Not handled correctly. */
988 HOWTO (R_MIPS_INSERT_A
, /* type */
990 2, /* size (0 = byte, 1 = short, 2 = long) */
992 FALSE
, /* pc_relative */
994 complain_overflow_dont
, /* complain_on_overflow */
995 bfd_elf_generic_reloc
, /* special_function */
996 "R_MIPS_INSERT_A", /* name */
997 FALSE
, /* partial_inplace */
999 0xffffffff, /* dst_mask */
1000 FALSE
), /* pcrel_offset */
1002 /* Insert the addend as an instruction, and change all relocations
1003 to refer to the old instruction at the address. */
1004 /* FIXME: Not handled correctly. */
1005 HOWTO (R_MIPS_INSERT_B
, /* type */
1007 2, /* size (0 = byte, 1 = short, 2 = long) */
1009 FALSE
, /* pc_relative */
1011 complain_overflow_dont
, /* complain_on_overflow */
1012 bfd_elf_generic_reloc
, /* special_function */
1013 "R_MIPS_INSERT_B", /* name */
1014 FALSE
, /* partial_inplace */
1016 0xffffffff, /* dst_mask */
1017 FALSE
), /* pcrel_offset */
1019 /* Delete a 32 bit instruction. */
1020 /* FIXME: Not handled correctly. */
1021 HOWTO (R_MIPS_DELETE
, /* type */
1023 2, /* size (0 = byte, 1 = short, 2 = long) */
1025 FALSE
, /* pc_relative */
1027 complain_overflow_dont
, /* complain_on_overflow */
1028 bfd_elf_generic_reloc
, /* special_function */
1029 "R_MIPS_DELETE", /* name */
1030 FALSE
, /* partial_inplace */
1032 0xffffffff, /* dst_mask */
1033 FALSE
), /* pcrel_offset */
1035 /* Get the higher value of a 64 bit addend. */
1036 HOWTO (R_MIPS_HIGHER
, /* type */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1040 FALSE
, /* pc_relative */
1042 complain_overflow_dont
, /* complain_on_overflow */
1043 bfd_elf_generic_reloc
, /* special_function */
1044 "R_MIPS_HIGHER", /* name */
1045 FALSE
, /* partial_inplace */
1047 0x0000ffff, /* dst_mask */
1048 FALSE
), /* pcrel_offset */
1050 /* Get the highest value of a 64 bit addend. */
1051 HOWTO (R_MIPS_HIGHEST
, /* type */
1053 2, /* size (0 = byte, 1 = short, 2 = long) */
1055 FALSE
, /* pc_relative */
1057 complain_overflow_dont
, /* complain_on_overflow */
1058 bfd_elf_generic_reloc
, /* special_function */
1059 "R_MIPS_HIGHEST", /* name */
1060 FALSE
, /* partial_inplace */
1062 0x0000ffff, /* dst_mask */
1063 FALSE
), /* pcrel_offset */
1065 /* High 16 bits of displacement in global offset table. */
1066 HOWTO (R_MIPS_CALL_HI16
, /* type */
1068 2, /* size (0 = byte, 1 = short, 2 = long) */
1070 FALSE
, /* pc_relative */
1072 complain_overflow_dont
, /* complain_on_overflow */
1073 bfd_elf_generic_reloc
, /* special_function */
1074 "R_MIPS_CALL_HI16", /* name */
1075 FALSE
, /* partial_inplace */
1077 0x0000ffff, /* dst_mask */
1078 FALSE
), /* pcrel_offset */
1080 /* Low 16 bits of displacement in global offset table. */
1081 HOWTO (R_MIPS_CALL_LO16
, /* type */
1083 2, /* size (0 = byte, 1 = short, 2 = long) */
1085 FALSE
, /* pc_relative */
1087 complain_overflow_dont
, /* complain_on_overflow */
1088 bfd_elf_generic_reloc
, /* special_function */
1089 "R_MIPS_CALL_LO16", /* name */
1090 FALSE
, /* partial_inplace */
1092 0x0000ffff, /* dst_mask */
1093 FALSE
), /* pcrel_offset */
1095 /* Section displacement, used by an associated event location section. */
1096 HOWTO (R_MIPS_SCN_DISP
, /* type */
1098 2, /* size (0 = byte, 1 = short, 2 = long) */
1100 FALSE
, /* pc_relative */
1102 complain_overflow_dont
, /* complain_on_overflow */
1103 bfd_elf_generic_reloc
, /* special_function */
1104 "R_MIPS_SCN_DISP", /* name */
1105 FALSE
, /* partial_inplace */
1107 0xffffffff, /* dst_mask */
1108 FALSE
), /* pcrel_offset */
1110 HOWTO (R_MIPS_REL16
, /* type */
1112 1, /* size (0 = byte, 1 = short, 2 = long) */
1114 FALSE
, /* pc_relative */
1116 complain_overflow_signed
, /* complain_on_overflow */
1117 bfd_elf_generic_reloc
, /* special_function */
1118 "R_MIPS_REL16", /* name */
1119 FALSE
, /* partial_inplace */
1121 0xffff, /* dst_mask */
1122 FALSE
), /* pcrel_offset */
1124 /* These two are obsolete. */
1125 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
1126 EMPTY_HOWTO (R_MIPS_PJUMP
),
1128 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1129 It must be used for multigot GOT's (and only there). */
1130 HOWTO (R_MIPS_RELGOT
, /* type */
1132 2, /* size (0 = byte, 1 = short, 2 = long) */
1134 FALSE
, /* pc_relative */
1136 complain_overflow_dont
, /* complain_on_overflow */
1137 bfd_elf_generic_reloc
, /* special_function */
1138 "R_MIPS_RELGOT", /* name */
1139 FALSE
, /* partial_inplace */
1141 0xffffffff, /* dst_mask */
1142 FALSE
), /* pcrel_offset */
1144 /* Protected jump conversion. This is an optimization hint. No
1145 relocation is required for correctness. */
1146 HOWTO (R_MIPS_JALR
, /* type */
1148 2, /* size (0 = byte, 1 = short, 2 = long) */
1150 FALSE
, /* pc_relative */
1152 complain_overflow_dont
, /* complain_on_overflow */
1153 bfd_elf_generic_reloc
, /* special_function */
1154 "R_MIPS_JALR", /* name */
1155 FALSE
, /* partial_inplace */
1157 0x00000000, /* dst_mask */
1158 FALSE
), /* pcrel_offset */
1161 /* The reloc used for the mips16 jump instruction. */
1162 static reloc_howto_type elf_mips16_jump_howto
=
1163 HOWTO (R_MIPS16_26
, /* type */
1165 2, /* size (0 = byte, 1 = short, 2 = long) */
1167 FALSE
, /* pc_relative */
1169 complain_overflow_dont
, /* complain_on_overflow */
1170 /* This needs complex overflow
1171 detection, because the upper four
1172 bits must match the PC. */
1173 mips16_jump_reloc
, /* special_function */
1174 "R_MIPS16_26", /* name */
1175 TRUE
, /* partial_inplace */
1176 0x3ffffff, /* src_mask */
1177 0x3ffffff, /* dst_mask */
1178 FALSE
); /* pcrel_offset */
1180 /* The reloc used for the mips16 gprel instruction. */
1181 static reloc_howto_type elf_mips16_gprel_howto
=
1182 HOWTO (R_MIPS16_GPREL
, /* type */
1184 2, /* size (0 = byte, 1 = short, 2 = long) */
1186 FALSE
, /* pc_relative */
1188 complain_overflow_signed
, /* complain_on_overflow */
1189 mips16_gprel_reloc
, /* special_function */
1190 "R_MIPS16_GPREL", /* name */
1191 TRUE
, /* partial_inplace */
1192 0x07ff001f, /* src_mask */
1193 0x07ff001f, /* dst_mask */
1194 FALSE
); /* pcrel_offset */
1196 /* GNU extension to record C++ vtable hierarchy */
1197 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
1198 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
1200 2, /* size (0 = byte, 1 = short, 2 = long) */
1202 FALSE
, /* pc_relative */
1204 complain_overflow_dont
, /* complain_on_overflow */
1205 NULL
, /* special_function */
1206 "R_MIPS_GNU_VTINHERIT", /* name */
1207 FALSE
, /* partial_inplace */
1210 FALSE
); /* pcrel_offset */
1212 /* GNU extension to record C++ vtable member usage */
1213 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
1214 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
1216 2, /* size (0 = byte, 1 = short, 2 = long) */
1218 FALSE
, /* pc_relative */
1220 complain_overflow_dont
, /* complain_on_overflow */
1221 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
1222 "R_MIPS_GNU_VTENTRY", /* name */
1223 FALSE
, /* partial_inplace */
1226 FALSE
); /* pcrel_offset */
1228 /* Swap in a MIPS 64-bit Rel reloc. */
1231 mips_elf64_swap_reloc_in (abfd
, src
, dst
)
1233 const Elf64_Mips_External_Rel
*src
;
1234 Elf64_Mips_Internal_Rela
*dst
;
1236 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1237 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1238 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1239 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1240 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1241 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1245 /* Swap in a MIPS 64-bit Rela reloc. */
1248 mips_elf64_swap_reloca_in (abfd
, src
, dst
)
1250 const Elf64_Mips_External_Rela
*src
;
1251 Elf64_Mips_Internal_Rela
*dst
;
1253 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1254 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1255 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1256 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1257 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1258 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1259 dst
->r_addend
= H_GET_S64 (abfd
, src
->r_addend
);
1262 /* Swap out a MIPS 64-bit Rel reloc. */
1265 mips_elf64_swap_reloc_out (abfd
, src
, dst
)
1267 const Elf64_Mips_Internal_Rela
*src
;
1268 Elf64_Mips_External_Rel
*dst
;
1270 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1271 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1272 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1273 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1274 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1275 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1278 /* Swap out a MIPS 64-bit Rela reloc. */
1281 mips_elf64_swap_reloca_out (abfd
, src
, dst
)
1283 const Elf64_Mips_Internal_Rela
*src
;
1284 Elf64_Mips_External_Rela
*dst
;
1286 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1287 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1288 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1289 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1290 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1291 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1292 H_PUT_S64 (abfd
, src
->r_addend
, dst
->r_addend
);
1295 /* Swap in a MIPS 64-bit Rel reloc. */
1298 mips_elf64_be_swap_reloc_in (abfd
, src
, dst
)
1300 const bfd_byte
*src
;
1301 Elf_Internal_Rela
*dst
;
1303 Elf64_Mips_Internal_Rela mirel
;
1305 mips_elf64_swap_reloc_in (abfd
,
1306 (const Elf64_Mips_External_Rel
*) src
,
1309 dst
[0].r_offset
= mirel
.r_offset
;
1310 dst
[0].r_info
= ELF64_R_INFO (mirel
.r_sym
, mirel
.r_type
);
1311 dst
[0].r_addend
= 0;
1312 dst
[1].r_offset
= mirel
.r_offset
;
1313 dst
[1].r_info
= ELF64_R_INFO (mirel
.r_ssym
, mirel
.r_type2
);
1314 dst
[1].r_addend
= 0;
1315 dst
[2].r_offset
= mirel
.r_offset
;
1316 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirel
.r_type3
);
1317 dst
[2].r_addend
= 0;
1320 /* Swap in a MIPS 64-bit Rela reloc. */
1323 mips_elf64_be_swap_reloca_in (abfd
, src
, dst
)
1325 const bfd_byte
*src
;
1326 Elf_Internal_Rela
*dst
;
1328 Elf64_Mips_Internal_Rela mirela
;
1330 mips_elf64_swap_reloca_in (abfd
,
1331 (const Elf64_Mips_External_Rela
*) src
,
1334 dst
[0].r_offset
= mirela
.r_offset
;
1335 dst
[0].r_info
= ELF64_R_INFO (mirela
.r_sym
, mirela
.r_type
);
1336 dst
[0].r_addend
= mirela
.r_addend
;
1337 dst
[1].r_offset
= mirela
.r_offset
;
1338 dst
[1].r_info
= ELF64_R_INFO (mirela
.r_ssym
, mirela
.r_type2
);
1339 dst
[1].r_addend
= 0;
1340 dst
[2].r_offset
= mirela
.r_offset
;
1341 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirela
.r_type3
);
1342 dst
[2].r_addend
= 0;
1345 /* Swap out a MIPS 64-bit Rel reloc. */
1348 mips_elf64_be_swap_reloc_out (abfd
, src
, dst
)
1350 const Elf_Internal_Rela
*src
;
1353 Elf64_Mips_Internal_Rela mirel
;
1355 mirel
.r_offset
= src
[0].r_offset
;
1356 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1358 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1361 mirel
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1362 mirel
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1363 mirel
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1364 mirel
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1365 mirel
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1367 mips_elf64_swap_reloc_out (abfd
, &mirel
,
1368 (Elf64_Mips_External_Rel
*) dst
);
1371 /* Swap out a MIPS 64-bit Rela reloc. */
1374 mips_elf64_be_swap_reloca_out (abfd
, src
, dst
)
1376 const Elf_Internal_Rela
*src
;
1379 Elf64_Mips_Internal_Rela mirela
;
1381 mirela
.r_offset
= src
[0].r_offset
;
1382 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1383 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1385 mirela
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1386 mirela
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1387 mirela
.r_addend
= src
[0].r_addend
;
1388 BFD_ASSERT(src
[1].r_addend
== 0);
1389 BFD_ASSERT(src
[2].r_addend
== 0);
1391 mirela
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1392 mirela
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1393 mirela
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1395 mips_elf64_swap_reloca_out (abfd
, &mirela
,
1396 (Elf64_Mips_External_Rela
*) dst
);
1399 /* Do a R_MIPS_HI16 relocation. */
1401 static bfd_reloc_status_type
1402 mips_elf64_hi16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1403 output_bfd
, error_message
)
1404 bfd
*abfd ATTRIBUTE_UNUSED
;
1405 arelent
*reloc_entry
;
1407 PTR data ATTRIBUTE_UNUSED
;
1408 asection
*input_section
;
1410 char **error_message ATTRIBUTE_UNUSED
;
1412 /* If we're relocating, and this is an external symbol, we don't
1413 want to change anything. */
1414 if (output_bfd
!= (bfd
*) NULL
1415 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1416 && (! reloc_entry
->howto
->partial_inplace
1417 || reloc_entry
->addend
== 0))
1419 reloc_entry
->address
+= input_section
->output_offset
;
1420 return bfd_reloc_ok
;
1423 if (((reloc_entry
->addend
& 0xffff) + 0x8000) & ~0xffff)
1424 reloc_entry
->addend
+= 0x8000;
1426 return bfd_reloc_continue
;
1429 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1430 table used for PIC code. If the symbol is an external symbol, the
1431 instruction is modified to contain the offset of the appropriate
1432 entry in the global offset table. If the symbol is a section
1433 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1434 addends are combined to form the real addend against the section
1435 symbol; the GOT16 is modified to contain the offset of an entry in
1436 the global offset table, and the LO16 is modified to offset it
1437 appropriately. Thus an offset larger than 16 bits requires a
1438 modified value in the global offset table.
1440 This implementation suffices for the assembler, but the linker does
1441 not yet know how to create global offset tables. */
1443 static bfd_reloc_status_type
1444 mips_elf64_got16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1445 output_bfd
, error_message
)
1447 arelent
*reloc_entry
;
1450 asection
*input_section
;
1452 char **error_message
;
1454 /* If we're relocating, and this is a local symbol, we can handle it
1455 just like an R_MIPS_HI16. */
1456 if (output_bfd
!= (bfd
*) NULL
1457 && (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1458 return mips_elf64_hi16_reloc (abfd
, reloc_entry
, symbol
, data
,
1459 input_section
, output_bfd
, error_message
);
1462 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1463 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
1464 input_section
, output_bfd
, error_message
);
1467 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1468 dangerous relocation. */
1471 mips_elf64_assign_gp (output_bfd
, pgp
)
1479 /* If we've already figured out what GP will be, just return it. */
1480 *pgp
= _bfd_get_gp_value (output_bfd
);
1484 count
= bfd_get_symcount (output_bfd
);
1485 sym
= bfd_get_outsymbols (output_bfd
);
1487 /* The linker script will have created a symbol named `_gp' with the
1488 appropriate value. */
1489 if (sym
== (asymbol
**) NULL
)
1493 for (i
= 0; i
< count
; i
++, sym
++)
1495 register const char *name
;
1497 name
= bfd_asymbol_name (*sym
);
1498 if (*name
== '_' && strcmp (name
, "_gp") == 0)
1500 *pgp
= bfd_asymbol_value (*sym
);
1501 _bfd_set_gp_value (output_bfd
, *pgp
);
1509 /* Only get the error once. */
1511 _bfd_set_gp_value (output_bfd
, *pgp
);
1518 /* We have to figure out the gp value, so that we can adjust the
1519 symbol value correctly. We look up the symbol _gp in the output
1520 BFD. If we can't find it, we're stuck. We cache it in the ELF
1521 target data. We don't need to adjust the symbol value for an
1522 external symbol if we are producing relocateable output. */
1524 static bfd_reloc_status_type
1525 mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
, pgp
)
1528 bfd_boolean relocateable
;
1529 char **error_message
;
1532 if (bfd_is_und_section (symbol
->section
)
1536 return bfd_reloc_undefined
;
1539 *pgp
= _bfd_get_gp_value (output_bfd
);
1542 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
1546 /* Make up a value. */
1547 *pgp
= symbol
->section
->output_section
->vma
/*+ 0x4000*/;
1548 _bfd_set_gp_value (output_bfd
, *pgp
);
1550 else if (!mips_elf64_assign_gp (output_bfd
, pgp
))
1553 (char *) _("GP relative relocation when _gp not defined");
1554 return bfd_reloc_dangerous
;
1558 return bfd_reloc_ok
;
1561 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1562 become the offset from the gp register. */
1564 static bfd_reloc_status_type
1565 mips_elf64_gprel16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1566 output_bfd
, error_message
)
1568 arelent
*reloc_entry
;
1571 asection
*input_section
;
1573 char **error_message
;
1575 bfd_boolean relocateable
;
1576 bfd_reloc_status_type ret
;
1579 /* If we're relocating, and this is an external symbol with no
1580 addend, we don't want to change anything. We will only have an
1581 addend if this is a newly created reloc, not read from an ELF
1583 if (output_bfd
!= (bfd
*) NULL
1584 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1585 && (! reloc_entry
->howto
->partial_inplace
1586 || reloc_entry
->addend
== 0))
1588 reloc_entry
->address
+= input_section
->output_offset
;
1589 return bfd_reloc_ok
;
1592 if (output_bfd
!= (bfd
*) NULL
)
1593 relocateable
= TRUE
;
1596 relocateable
= FALSE
;
1597 output_bfd
= symbol
->section
->output_section
->owner
;
1600 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1602 if (ret
!= bfd_reloc_ok
)
1605 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1606 input_section
, relocateable
,
1610 /* Do a R_MIPS_LITERAL relocation. */
1612 static bfd_reloc_status_type
1613 mips_elf64_literal_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1614 output_bfd
, error_message
)
1616 arelent
*reloc_entry
;
1619 asection
*input_section
;
1621 char **error_message
;
1623 bfd_boolean relocateable
;
1624 bfd_reloc_status_type ret
;
1627 /* If we're relocating, and this is an external symbol, we don't
1628 want to change anything. */
1629 if (output_bfd
!= (bfd
*) NULL
1630 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1631 && (! reloc_entry
->howto
->partial_inplace
1632 || reloc_entry
->addend
== 0))
1634 reloc_entry
->address
+= input_section
->output_offset
;
1635 return bfd_reloc_ok
;
1638 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1639 if (output_bfd
!= (bfd
*) NULL
)
1640 relocateable
= TRUE
;
1643 relocateable
= FALSE
;
1644 output_bfd
= symbol
->section
->output_section
->owner
;
1647 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1649 if (ret
!= bfd_reloc_ok
)
1652 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1653 input_section
, relocateable
,
1657 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1658 become the offset from the gp register. */
1660 static bfd_reloc_status_type
1661 mips_elf64_gprel32_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1662 output_bfd
, error_message
)
1664 arelent
*reloc_entry
;
1667 asection
*input_section
;
1669 char **error_message
;
1671 bfd_boolean relocateable
;
1672 bfd_reloc_status_type ret
;
1677 /* If we're relocating, and this is an external symbol with no
1678 addend, we don't want to change anything. We will only have an
1679 addend if this is a newly created reloc, not read from an ELF
1681 if (output_bfd
!= (bfd
*) NULL
1682 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1683 && reloc_entry
->addend
== 0)
1685 *error_message
= (char *)
1686 _("32bits gp relative relocation occurs for an external symbol");
1687 return bfd_reloc_outofrange
;
1690 if (output_bfd
!= (bfd
*) NULL
)
1692 relocateable
= TRUE
;
1693 gp
= _bfd_get_gp_value (output_bfd
);
1697 relocateable
= FALSE
;
1698 output_bfd
= symbol
->section
->output_section
->owner
;
1700 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
,
1701 error_message
, &gp
);
1702 if (ret
!= bfd_reloc_ok
)
1706 if (bfd_is_com_section (symbol
->section
))
1709 relocation
= symbol
->value
;
1711 relocation
+= symbol
->section
->output_section
->vma
;
1712 relocation
+= symbol
->section
->output_offset
;
1714 if (reloc_entry
->address
> input_section
->_cooked_size
)
1715 return bfd_reloc_outofrange
;
1717 if (reloc_entry
->howto
->src_mask
== 0)
1719 /* This case arises with the 64-bit MIPS ELF ABI. */
1723 val
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1725 /* Set val to the offset into the section or symbol. */
1726 val
+= reloc_entry
->addend
;
1728 /* Adjust val for the final section location and GP value. If we
1729 are producing relocateable output, we don't want to do this for
1730 an external symbol. */
1732 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1733 val
+= relocation
- gp
;
1735 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
1738 reloc_entry
->address
+= input_section
->output_offset
;
1740 return bfd_reloc_ok
;
1743 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1744 the rest is at bits 6-10. The bitpos already got right by the howto. */
1746 static bfd_reloc_status_type
1747 mips_elf64_shift6_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1748 output_bfd
, error_message
)
1749 bfd
*abfd ATTRIBUTE_UNUSED
;
1750 arelent
*reloc_entry
;
1752 PTR data ATTRIBUTE_UNUSED
;
1753 asection
*input_section
;
1755 char **error_message ATTRIBUTE_UNUSED
;
1757 /* If we're relocating, and this is an external symbol, we don't
1758 want to change anything. */
1759 if (output_bfd
!= (bfd
*) NULL
1760 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1761 && (! reloc_entry
->howto
->partial_inplace
1762 || reloc_entry
->addend
== 0))
1764 reloc_entry
->address
+= input_section
->output_offset
;
1765 return bfd_reloc_ok
;
1768 reloc_entry
->addend
= (reloc_entry
->addend
& 0x00007c0)
1769 | (reloc_entry
->addend
& 0x00000800) >> 9;
1771 return bfd_reloc_continue
;
1774 /* Handle a mips16 jump. */
1776 static bfd_reloc_status_type
1777 mips16_jump_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1778 output_bfd
, error_message
)
1779 bfd
*abfd ATTRIBUTE_UNUSED
;
1780 arelent
*reloc_entry
;
1782 PTR data ATTRIBUTE_UNUSED
;
1783 asection
*input_section
;
1785 char **error_message ATTRIBUTE_UNUSED
;
1787 if (output_bfd
!= (bfd
*) NULL
1788 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1789 && (! reloc_entry
->howto
->partial_inplace
1790 || reloc_entry
->addend
== 0))
1792 reloc_entry
->address
+= input_section
->output_offset
;
1793 return bfd_reloc_ok
;
1798 static bfd_boolean warned
;
1801 (*_bfd_error_handler
)
1802 (_("Linking mips16 objects into %s format is not supported"),
1803 bfd_get_target (input_section
->output_section
->owner
));
1807 return bfd_reloc_undefined
;
1810 /* Handle a mips16 GP relative reloc. */
1812 static bfd_reloc_status_type
1813 mips16_gprel_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1814 output_bfd
, error_message
)
1816 arelent
*reloc_entry
;
1819 asection
*input_section
;
1821 char **error_message
;
1823 bfd_boolean relocateable
;
1824 bfd_reloc_status_type ret
;
1826 unsigned short extend
, insn
;
1827 unsigned long final
;
1829 /* If we're relocating, and this is an external symbol with no
1830 addend, we don't want to change anything. We will only have an
1831 addend if this is a newly created reloc, not read from an ELF
1833 if (output_bfd
!= NULL
1834 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1835 && reloc_entry
->addend
== 0)
1837 reloc_entry
->address
+= input_section
->output_offset
;
1838 return bfd_reloc_ok
;
1841 if (output_bfd
!= NULL
)
1842 relocateable
= TRUE
;
1845 relocateable
= FALSE
;
1846 output_bfd
= symbol
->section
->output_section
->owner
;
1849 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1851 if (ret
!= bfd_reloc_ok
)
1854 if (reloc_entry
->address
> input_section
->_cooked_size
)
1855 return bfd_reloc_outofrange
;
1857 /* Pick up the mips16 extend instruction and the real instruction. */
1858 extend
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1859 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1861 /* Stuff the current addend back as a 32 bit value, do the usual
1862 relocation, and then clean up. */
1864 (bfd_vma
) (((extend
& 0x1f) << 11)
1867 (bfd_byte
*) data
+ reloc_entry
->address
);
1869 ret
= _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1870 input_section
, relocateable
, data
, gp
);
1872 final
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1874 (bfd_vma
) ((extend
& 0xf800)
1875 | ((final
>> 11) & 0x1f)
1877 (bfd_byte
*) data
+ reloc_entry
->address
);
1879 (bfd_vma
) ((insn
& 0xffe0)
1881 (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1886 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1888 struct elf_reloc_map
{
1889 bfd_reloc_code_real_type bfd_val
;
1890 enum elf_mips_reloc_type elf_val
;
1893 static const struct elf_reloc_map mips_reloc_map
[] =
1895 { BFD_RELOC_NONE
, R_MIPS_NONE
},
1896 { BFD_RELOC_16
, R_MIPS_16
},
1897 { BFD_RELOC_32
, R_MIPS_32
},
1898 /* There is no BFD reloc for R_MIPS_REL32. */
1899 { BFD_RELOC_64
, R_MIPS_64
},
1900 { BFD_RELOC_CTOR
, R_MIPS_64
},
1901 { BFD_RELOC_16_PCREL_S2
, R_MIPS_PC16
},
1902 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
1903 { BFD_RELOC_LO16
, R_MIPS_LO16
},
1904 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
1905 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
1906 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
1907 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
1908 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
1909 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
1910 { BFD_RELOC_MIPS_SHIFT5
, R_MIPS_SHIFT5
},
1911 { BFD_RELOC_MIPS_SHIFT6
, R_MIPS_SHIFT6
},
1912 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
},
1913 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
1914 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
1915 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
1916 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
1917 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
1918 { BFD_RELOC_MIPS_INSERT_A
, R_MIPS_INSERT_A
},
1919 { BFD_RELOC_MIPS_INSERT_B
, R_MIPS_INSERT_B
},
1920 { BFD_RELOC_MIPS_DELETE
, R_MIPS_DELETE
},
1921 { BFD_RELOC_MIPS_HIGHEST
, R_MIPS_HIGHEST
},
1922 { BFD_RELOC_MIPS_HIGHER
, R_MIPS_HIGHER
},
1923 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
1924 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
1925 { BFD_RELOC_MIPS_SCN_DISP
, R_MIPS_SCN_DISP
},
1926 { BFD_RELOC_MIPS_REL16
, R_MIPS_REL16
},
1927 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1928 { BFD_RELOC_MIPS_RELGOT
, R_MIPS_RELGOT
},
1929 { BFD_RELOC_MIPS_JALR
, R_MIPS_JALR
}
1932 /* Given a BFD reloc type, return a howto structure. */
1934 static reloc_howto_type
*
1935 bfd_elf64_bfd_reloc_type_lookup (abfd
, code
)
1936 bfd
*abfd ATTRIBUTE_UNUSED
;
1937 bfd_reloc_code_real_type code
;
1940 /* FIXME: We default to RELA here instead of choosing the right
1941 relocation variant. */
1942 reloc_howto_type
*howto_table
= mips_elf64_howto_table_rela
;
1944 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
1947 if (mips_reloc_map
[i
].bfd_val
== code
)
1948 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
1953 case BFD_RELOC_MIPS16_JMP
:
1954 return &elf_mips16_jump_howto
;
1955 case BFD_RELOC_MIPS16_GPREL
:
1956 return &elf_mips16_gprel_howto
;
1957 case BFD_RELOC_VTABLE_INHERIT
:
1958 return &elf_mips_gnu_vtinherit_howto
;
1959 case BFD_RELOC_VTABLE_ENTRY
:
1960 return &elf_mips_gnu_vtentry_howto
;
1962 bfd_set_error (bfd_error_bad_value
);
1967 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1969 static reloc_howto_type
*
1970 mips_elf64_rtype_to_howto (r_type
, rela_p
)
1971 unsigned int r_type
;
1977 return &elf_mips16_jump_howto
;
1978 case R_MIPS16_GPREL
:
1979 return &elf_mips16_gprel_howto
;
1980 case R_MIPS_GNU_VTINHERIT
:
1981 return &elf_mips_gnu_vtinherit_howto
;
1982 case R_MIPS_GNU_VTENTRY
:
1983 return &elf_mips_gnu_vtentry_howto
;
1985 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
1987 return &mips_elf64_howto_table_rela
[r_type
];
1989 return &mips_elf64_howto_table_rel
[r_type
];
1994 /* Prevent relocation handling by bfd for MIPS ELF64. */
1997 mips_elf64_info_to_howto_rel (abfd
, cache_ptr
, dst
)
1998 bfd
*abfd ATTRIBUTE_UNUSED
;
1999 arelent
*cache_ptr ATTRIBUTE_UNUSED
;
2000 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
;
2006 mips_elf64_info_to_howto_rela (abfd
, cache_ptr
, dst
)
2007 bfd
*abfd ATTRIBUTE_UNUSED
;
2008 arelent
*cache_ptr ATTRIBUTE_UNUSED
;
2009 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
;
2014 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2015 to three relocs, we must tell the user to allocate more space. */
2018 mips_elf64_get_reloc_upper_bound (abfd
, sec
)
2019 bfd
*abfd ATTRIBUTE_UNUSED
;
2022 return (sec
->reloc_count
* 3 + 1) * sizeof (arelent
*);
2025 /* Read the relocations from one reloc section. */
2028 mips_elf64_slurp_one_reloc_table (abfd
, asect
, symbols
, rel_hdr
)
2032 const Elf_Internal_Shdr
*rel_hdr
;
2034 PTR allocated
= NULL
;
2035 bfd_byte
*native_relocs
;
2041 reloc_howto_type
*howto_table
;
2043 allocated
= (PTR
) bfd_malloc (rel_hdr
->sh_size
);
2044 if (allocated
== NULL
)
2047 if (bfd_seek (abfd
, rel_hdr
->sh_offset
, SEEK_SET
) != 0
2048 || (bfd_bread (allocated
, rel_hdr
->sh_size
, abfd
) != rel_hdr
->sh_size
))
2051 native_relocs
= (bfd_byte
*) allocated
;
2053 relents
= asect
->relocation
+ asect
->reloc_count
;
2055 entsize
= rel_hdr
->sh_entsize
;
2056 BFD_ASSERT (entsize
== sizeof (Elf64_Mips_External_Rel
)
2057 || entsize
== sizeof (Elf64_Mips_External_Rela
));
2059 count
= rel_hdr
->sh_size
/ entsize
;
2061 if (entsize
== sizeof (Elf64_Mips_External_Rel
))
2062 howto_table
= mips_elf64_howto_table_rel
;
2064 howto_table
= mips_elf64_howto_table_rela
;
2067 for (i
= 0; i
< count
; i
++, native_relocs
+= entsize
)
2069 Elf64_Mips_Internal_Rela rela
;
2070 bfd_boolean used_sym
, used_ssym
;
2073 if (entsize
== sizeof (Elf64_Mips_External_Rela
))
2074 mips_elf64_swap_reloca_in (abfd
,
2075 (Elf64_Mips_External_Rela
*) native_relocs
,
2078 mips_elf64_swap_reloc_in (abfd
,
2079 (Elf64_Mips_External_Rel
*) native_relocs
,
2082 /* Each entry represents exactly three actual relocations. */
2086 for (ir
= 0; ir
< 3; ir
++)
2088 enum elf_mips_reloc_type type
;
2095 type
= (enum elf_mips_reloc_type
) rela
.r_type
;
2098 type
= (enum elf_mips_reloc_type
) rela
.r_type2
;
2101 type
= (enum elf_mips_reloc_type
) rela
.r_type3
;
2105 /* Some types require symbols, whereas some do not. */
2109 case R_MIPS_LITERAL
:
2110 case R_MIPS_INSERT_A
:
2111 case R_MIPS_INSERT_B
:
2113 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2119 if (rela
.r_sym
== 0)
2120 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2125 ps
= symbols
+ rela
.r_sym
- 1;
2127 if ((s
->flags
& BSF_SECTION_SYM
) == 0)
2128 relent
->sym_ptr_ptr
= ps
;
2130 relent
->sym_ptr_ptr
= s
->section
->symbol_ptr_ptr
;
2135 else if (! used_ssym
)
2137 switch (rela
.r_ssym
)
2140 relent
->sym_ptr_ptr
=
2141 bfd_abs_section_ptr
->symbol_ptr_ptr
;
2147 /* FIXME: I think these need to be handled using
2148 special howto structures. */
2160 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2165 /* The address of an ELF reloc is section relative for an
2166 object file, and absolute for an executable file or
2167 shared library. The address of a BFD reloc is always
2168 section relative. */
2169 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2170 relent
->address
= rela
.r_offset
;
2172 relent
->address
= rela
.r_offset
- asect
->vma
;
2174 relent
->addend
= rela
.r_addend
;
2176 relent
->howto
= &howto_table
[(int) type
];
2182 asect
->reloc_count
+= (relent
- relents
) / 3;
2184 if (allocated
!= NULL
)
2190 if (allocated
!= NULL
)
2195 /* Read the relocations. On Irix 6, there can be two reloc sections
2196 associated with a single data section. */
2199 mips_elf64_slurp_reloc_table (abfd
, asect
, symbols
, dynamic
)
2203 bfd_boolean dynamic
;
2206 struct bfd_elf_section_data
* const d
= elf_section_data (asect
);
2210 bfd_set_error (bfd_error_invalid_operation
);
2214 if (asect
->relocation
!= NULL
2215 || (asect
->flags
& SEC_RELOC
) == 0
2216 || asect
->reloc_count
== 0)
2219 /* Allocate space for 3 arelent structures for each Rel structure. */
2220 amt
= asect
->reloc_count
;
2221 amt
*= 3 * sizeof (arelent
);
2222 asect
->relocation
= (arelent
*) bfd_alloc (abfd
, amt
);
2223 if (asect
->relocation
== NULL
)
2226 /* The slurp_one_reloc_table routine increments reloc_count. */
2227 asect
->reloc_count
= 0;
2229 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
, symbols
, &d
->rel_hdr
))
2231 if (d
->rel_hdr2
!= NULL
)
2233 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
, symbols
,
2241 /* Write out the relocations. */
2244 mips_elf64_write_relocs (abfd
, sec
, data
)
2249 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2251 Elf_Internal_Shdr
*rel_hdr
;
2254 /* If we have already failed, don't do anything. */
2258 if ((sec
->flags
& SEC_RELOC
) == 0)
2261 /* The linker backend writes the relocs out itself, and sets the
2262 reloc_count field to zero to inhibit writing them here. Also,
2263 sometimes the SEC_RELOC flag gets set even when there aren't any
2265 if (sec
->reloc_count
== 0)
2268 /* We can combine up to three relocs that refer to the same address
2269 if the latter relocs have no associated symbol. */
2271 for (idx
= 0; idx
< sec
->reloc_count
; idx
++)
2278 addr
= sec
->orelocation
[idx
]->address
;
2279 for (i
= 0; i
< 2; i
++)
2283 if (idx
+ 1 >= sec
->reloc_count
)
2285 r
= sec
->orelocation
[idx
+ 1];
2286 if (r
->address
!= addr
2287 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2288 || (*r
->sym_ptr_ptr
)->value
!= 0)
2291 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2297 rel_hdr
= &elf_section_data (sec
)->rel_hdr
;
2299 /* Do the actual relocation. */
2301 if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rel
))
2302 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, &count
, data
);
2303 else if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rela
))
2304 mips_elf64_write_rela (abfd
, sec
, rel_hdr
, &count
, data
);
2310 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, count
, data
)
2313 Elf_Internal_Shdr
*rel_hdr
;
2317 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2318 Elf64_Mips_External_Rel
*ext_rel
;
2320 asymbol
*last_sym
= 0;
2321 int last_sym_idx
= 0;
2323 rel_hdr
->sh_size
= (bfd_vma
)(rel_hdr
->sh_entsize
* *count
);
2324 rel_hdr
->contents
= (PTR
) bfd_alloc (abfd
, rel_hdr
->sh_size
);
2325 if (rel_hdr
->contents
== NULL
)
2331 ext_rel
= (Elf64_Mips_External_Rel
*) rel_hdr
->contents
;
2332 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rel
++)
2335 Elf64_Mips_Internal_Rela int_rel
;
2340 ptr
= sec
->orelocation
[idx
];
2342 /* The address of an ELF reloc is section relative for an object
2343 file, and absolute for an executable file or shared library.
2344 The address of a BFD reloc is always section relative. */
2345 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2346 int_rel
.r_offset
= ptr
->address
;
2348 int_rel
.r_offset
= ptr
->address
+ sec
->vma
;
2350 sym
= *ptr
->sym_ptr_ptr
;
2351 if (sym
== last_sym
)
2356 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2366 int_rel
.r_ssym
= RSS_UNDEF
;
2368 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2369 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2375 int_rel
.r_type
= ptr
->howto
->type
;
2376 int_rel
.r_type2
= (int) R_MIPS_NONE
;
2377 int_rel
.r_type3
= (int) R_MIPS_NONE
;
2379 for (i
= 0; i
< 2; i
++)
2383 if (idx
+ 1 >= sec
->reloc_count
)
2385 r
= sec
->orelocation
[idx
+ 1];
2386 if (r
->address
!= ptr
->address
2387 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2388 || (*r
->sym_ptr_ptr
)->value
!= 0)
2391 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2394 int_rel
.r_type2
= r
->howto
->type
;
2396 int_rel
.r_type3
= r
->howto
->type
;
2401 mips_elf64_swap_reloc_out (abfd
, &int_rel
, ext_rel
);
2404 BFD_ASSERT (ext_rel
- (Elf64_Mips_External_Rel
*) rel_hdr
->contents
2409 mips_elf64_write_rela (abfd
, sec
, rela_hdr
, count
, data
)
2412 Elf_Internal_Shdr
*rela_hdr
;
2416 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2417 Elf64_Mips_External_Rela
*ext_rela
;
2419 asymbol
*last_sym
= 0;
2420 int last_sym_idx
= 0;
2422 rela_hdr
->sh_size
= (bfd_vma
)(rela_hdr
->sh_entsize
* *count
);
2423 rela_hdr
->contents
= (PTR
) bfd_alloc (abfd
, rela_hdr
->sh_size
);
2424 if (rela_hdr
->contents
== NULL
)
2430 ext_rela
= (Elf64_Mips_External_Rela
*) rela_hdr
->contents
;
2431 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rela
++)
2434 Elf64_Mips_Internal_Rela int_rela
;
2439 ptr
= sec
->orelocation
[idx
];
2441 /* The address of an ELF reloc is section relative for an object
2442 file, and absolute for an executable file or shared library.
2443 The address of a BFD reloc is always section relative. */
2444 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2445 int_rela
.r_offset
= ptr
->address
;
2447 int_rela
.r_offset
= ptr
->address
+ sec
->vma
;
2449 sym
= *ptr
->sym_ptr_ptr
;
2450 if (sym
== last_sym
)
2455 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2465 int_rela
.r_addend
= ptr
->addend
;
2466 int_rela
.r_ssym
= RSS_UNDEF
;
2468 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2469 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2475 int_rela
.r_type
= ptr
->howto
->type
;
2476 int_rela
.r_type2
= (int) R_MIPS_NONE
;
2477 int_rela
.r_type3
= (int) R_MIPS_NONE
;
2479 for (i
= 0; i
< 2; i
++)
2483 if (idx
+ 1 >= sec
->reloc_count
)
2485 r
= sec
->orelocation
[idx
+ 1];
2486 if (r
->address
!= ptr
->address
2487 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2488 || (*r
->sym_ptr_ptr
)->value
!= 0)
2491 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2494 int_rela
.r_type2
= r
->howto
->type
;
2496 int_rela
.r_type3
= r
->howto
->type
;
2501 mips_elf64_swap_reloca_out (abfd
, &int_rela
, ext_rela
);
2504 BFD_ASSERT (ext_rela
- (Elf64_Mips_External_Rela
*) rela_hdr
->contents
2508 /* Set the right machine number for a MIPS ELF file. */
2511 mips_elf64_object_p (abfd
)
2516 /* Irix 6 is broken. Object file symbol tables are not always
2517 sorted correctly such that local symbols precede global symbols,
2518 and the sh_info field in the symbol table is not always right. */
2519 if (elf64_mips_irix_compat (abfd
) != ict_none
)
2520 elf_bad_symtab (abfd
) = TRUE
;
2522 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
2523 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
2527 /* Depending on the target vector we generate some version of Irix
2528 executables or "normal" MIPS ELF ABI executables. */
2529 static irix_compat_t
2530 elf64_mips_irix_compat (abfd
)
2533 if ((abfd
->xvec
== &bfd_elf64_bigmips_vec
)
2534 || (abfd
->xvec
== &bfd_elf64_littlemips_vec
))
2540 /* Support for core dump NOTE sections. */
2542 elf64_mips_grok_prstatus (abfd
, note
)
2544 Elf_Internal_Note
*note
;
2547 unsigned int raw_size
;
2549 switch (note
->descsz
)
2554 case 480: /* Linux/MIPS - N64 kernel */
2556 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
2559 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 32);
2568 /* Make a ".reg/999" section. */
2569 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
2570 raw_size
, note
->descpos
+ offset
);
2574 elf64_mips_grok_psinfo (abfd
, note
)
2576 Elf_Internal_Note
*note
;
2578 switch (note
->descsz
)
2583 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2584 elf_tdata (abfd
)->core_program
2585 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
2586 elf_tdata (abfd
)->core_command
2587 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
2590 /* Note that for some reason, a spurious space is tacked
2591 onto the end of the args in some (at least one anyway)
2592 implementations, so strip it off if it exists. */
2595 char *command
= elf_tdata (abfd
)->core_command
;
2596 int n
= strlen (command
);
2598 if (0 < n
&& command
[n
- 1] == ' ')
2599 command
[n
- 1] = '\0';
2605 /* ECOFF swapping routines. These are used when dealing with the
2606 .mdebug section, which is in the ECOFF debugging format. */
2607 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap
=
2609 /* Symbol table magic number. */
2611 /* Alignment of debugging information. E.g., 4. */
2613 /* Sizes of external symbolic information. */
2614 sizeof (struct hdr_ext
),
2615 sizeof (struct dnr_ext
),
2616 sizeof (struct pdr_ext
),
2617 sizeof (struct sym_ext
),
2618 sizeof (struct opt_ext
),
2619 sizeof (struct fdr_ext
),
2620 sizeof (struct rfd_ext
),
2621 sizeof (struct ext_ext
),
2622 /* Functions to swap in external symbolic data. */
2631 _bfd_ecoff_swap_tir_in
,
2632 _bfd_ecoff_swap_rndx_in
,
2633 /* Functions to swap out external symbolic data. */
2642 _bfd_ecoff_swap_tir_out
,
2643 _bfd_ecoff_swap_rndx_out
,
2644 /* Function to read in symbolic data. */
2645 _bfd_mips_elf_read_ecoff_info
2648 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2649 standard ELF. This structure is used to redirect the relocation
2650 handling routines. */
2652 const struct elf_size_info mips_elf64_size_info
=
2654 sizeof (Elf64_External_Ehdr
),
2655 sizeof (Elf64_External_Phdr
),
2656 sizeof (Elf64_External_Shdr
),
2657 sizeof (Elf64_Mips_External_Rel
),
2658 sizeof (Elf64_Mips_External_Rela
),
2659 sizeof (Elf64_External_Sym
),
2660 sizeof (Elf64_External_Dyn
),
2661 sizeof (Elf_External_Note
),
2662 4, /* hash-table entry size */
2663 3, /* internal relocations per external relocations */
2668 bfd_elf64_write_out_phdrs
,
2669 bfd_elf64_write_shdrs_and_ehdr
,
2670 mips_elf64_write_relocs
,
2671 bfd_elf64_swap_symbol_in
,
2672 bfd_elf64_swap_symbol_out
,
2673 mips_elf64_slurp_reloc_table
,
2674 bfd_elf64_slurp_symbol_table
,
2675 bfd_elf64_swap_dyn_in
,
2676 bfd_elf64_swap_dyn_out
,
2677 mips_elf64_be_swap_reloc_in
,
2678 mips_elf64_be_swap_reloc_out
,
2679 mips_elf64_be_swap_reloca_in
,
2680 mips_elf64_be_swap_reloca_out
2683 #define ELF_ARCH bfd_arch_mips
2684 #define ELF_MACHINE_CODE EM_MIPS
2686 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2687 a value of 0x1000, and we are compatible.
2688 FIXME: How does this affect NewABI? */
2689 #define ELF_MAXPAGESIZE 0x1000
2691 #define elf_backend_collect TRUE
2692 #define elf_backend_type_change_ok TRUE
2693 #define elf_backend_can_gc_sections TRUE
2694 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2695 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2696 #define elf_backend_object_p mips_elf64_object_p
2697 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2698 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2699 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2700 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2701 #define elf_backend_section_from_bfd_section \
2702 _bfd_mips_elf_section_from_bfd_section
2703 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2704 #define elf_backend_link_output_symbol_hook \
2705 _bfd_mips_elf_link_output_symbol_hook
2706 #define elf_backend_create_dynamic_sections \
2707 _bfd_mips_elf_create_dynamic_sections
2708 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2709 #define elf_backend_adjust_dynamic_symbol \
2710 _bfd_mips_elf_adjust_dynamic_symbol
2711 #define elf_backend_always_size_sections \
2712 _bfd_mips_elf_always_size_sections
2713 #define elf_backend_size_dynamic_sections \
2714 _bfd_mips_elf_size_dynamic_sections
2715 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2716 #define elf_backend_finish_dynamic_symbol \
2717 _bfd_mips_elf_finish_dynamic_symbol
2718 #define elf_backend_finish_dynamic_sections \
2719 _bfd_mips_elf_finish_dynamic_sections
2720 #define elf_backend_final_write_processing \
2721 _bfd_mips_elf_final_write_processing
2722 #define elf_backend_additional_program_headers \
2723 _bfd_mips_elf_additional_program_headers
2724 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2725 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2726 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2727 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2728 #define elf_backend_ignore_discarded_relocs \
2729 _bfd_mips_elf_ignore_discarded_relocs
2730 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2731 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2732 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2733 #define elf_backend_size_info mips_elf64_size_info
2735 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
2736 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
2738 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2739 #define elf_backend_plt_header_size 0
2741 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2742 work better/work only in RELA, so we default to this. */
2743 #define elf_backend_may_use_rel_p 1
2744 #define elf_backend_may_use_rela_p 1
2745 #define elf_backend_default_use_rela_p 1
2747 #define elf_backend_write_section _bfd_mips_elf_write_section
2749 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2750 MIPS-specific function only applies to IRIX5, which had no 64-bit
2752 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2753 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
2754 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2755 #define bfd_elf64_bfd_get_relocated_section_contents \
2756 _bfd_elf_mips_get_relocated_section_contents
2757 #define bfd_elf64_bfd_link_hash_table_create \
2758 _bfd_mips_elf_link_hash_table_create
2759 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2760 #define bfd_elf64_bfd_merge_private_bfd_data \
2761 _bfd_mips_elf_merge_private_bfd_data
2762 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2763 #define bfd_elf64_bfd_print_private_bfd_data \
2764 _bfd_mips_elf_print_private_bfd_data
2766 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2768 /* MIPS ELF64 archive functions. */
2769 #define bfd_elf64_archive_functions
2770 extern bfd_boolean bfd_elf64_archive_slurp_armap
2772 extern bfd_boolean bfd_elf64_archive_write_armap
2773 PARAMS ((bfd
*, unsigned int, struct orl
*, unsigned int, int));
2774 #define bfd_elf64_archive_slurp_extended_name_table \
2775 _bfd_archive_coff_slurp_extended_name_table
2776 #define bfd_elf64_archive_construct_extended_name_table \
2777 _bfd_archive_coff_construct_extended_name_table
2778 #define bfd_elf64_archive_truncate_arname \
2779 _bfd_archive_coff_truncate_arname
2780 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2781 #define bfd_elf64_archive_openr_next_archived_file \
2782 _bfd_archive_coff_openr_next_archived_file
2783 #define bfd_elf64_archive_get_elt_at_index \
2784 _bfd_archive_coff_get_elt_at_index
2785 #define bfd_elf64_archive_generic_stat_arch_elt \
2786 _bfd_archive_coff_generic_stat_arch_elt
2787 #define bfd_elf64_archive_update_armap_timestamp \
2788 _bfd_archive_coff_update_armap_timestamp
2790 /* The SGI style (n)64 NewABI. */
2791 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2792 #define TARGET_LITTLE_NAME "elf64-littlemips"
2793 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2794 #define TARGET_BIG_NAME "elf64-bigmips"
2796 #include "elf64-target.h"
2798 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2800 /* The SYSV-style 'traditional' (n)64 NewABI. */
2801 #undef TARGET_LITTLE_SYM
2802 #undef TARGET_LITTLE_NAME
2803 #undef TARGET_BIG_SYM
2804 #undef TARGET_BIG_NAME
2806 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2807 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2808 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2809 #define TARGET_BIG_NAME "elf64-tradbigmips"
2811 /* Include the target file again for this target. */
2812 #include "elf64-target.h"