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 long mips_elf64_canonicalize_reloc
95 PARAMS ((bfd
*, asection
*, arelent
**, asymbol
**));
96 static long mips_elf64_get_dynamic_reloc_upper_bound
PARAMS ((bfd
*));
97 static long mips_elf64_canonicalize_dynamic_reloc
98 PARAMS ((bfd
*, arelent
**, asymbol
**));
99 static bfd_boolean mips_elf64_slurp_one_reloc_table
100 PARAMS ((bfd
*, asection
*, Elf_Internal_Shdr
*, bfd_size_type
,
101 arelent
*, asymbol
**, bfd_boolean
));
102 static bfd_boolean mips_elf64_slurp_reloc_table
103 PARAMS ((bfd
*, asection
*, asymbol
**, bfd_boolean
));
104 static void mips_elf64_write_relocs
105 PARAMS ((bfd
*, asection
*, PTR
));
106 static void mips_elf64_write_rel
107 PARAMS((bfd
*, asection
*, Elf_Internal_Shdr
*, int *, PTR
));
108 static void mips_elf64_write_rela
109 PARAMS((bfd
*, asection
*, Elf_Internal_Shdr
*, int *, PTR
));
110 static bfd_reloc_status_type mips_elf64_hi16_reloc
111 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
112 static bfd_reloc_status_type mips_elf64_gprel16_reloc
113 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
114 static bfd_reloc_status_type mips_elf64_literal_reloc
115 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
116 static bfd_reloc_status_type mips_elf64_gprel32_reloc
117 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
118 static bfd_reloc_status_type mips_elf64_shift6_reloc
119 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
120 static bfd_reloc_status_type mips_elf64_got16_reloc
121 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
122 static bfd_reloc_status_type mips16_jump_reloc
123 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
124 static bfd_reloc_status_type mips16_gprel_reloc
125 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
126 static bfd_boolean mips_elf64_assign_gp
127 PARAMS ((bfd
*, bfd_vma
*));
128 static bfd_reloc_status_type mips_elf64_final_gp
129 PARAMS ((bfd
*, asymbol
*, bfd_boolean
, char **, bfd_vma
*));
130 static bfd_boolean mips_elf64_object_p
132 static irix_compat_t elf64_mips_irix_compat
134 static bfd_boolean elf64_mips_grok_prstatus
135 PARAMS ((bfd
*, Elf_Internal_Note
*));
136 static bfd_boolean elf64_mips_grok_psinfo
137 PARAMS ((bfd
*, Elf_Internal_Note
*));
139 extern const bfd_target bfd_elf64_bigmips_vec
;
140 extern const bfd_target bfd_elf64_littlemips_vec
;
142 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
143 from smaller values. Start with zero, widen, *then* decrement. */
144 #define MINUS_ONE (((bfd_vma)0) - 1)
146 /* The number of local .got entries we reserve. */
147 #define MIPS_RESERVED_GOTNO (2)
149 /* The relocation table used for SHT_REL sections. */
151 static reloc_howto_type mips_elf64_howto_table_rel
[] =
154 HOWTO (R_MIPS_NONE
, /* type */
156 0, /* size (0 = byte, 1 = short, 2 = long) */
158 FALSE
, /* pc_relative */
160 complain_overflow_dont
, /* complain_on_overflow */
161 bfd_elf_generic_reloc
, /* special_function */
162 "R_MIPS_NONE", /* name */
163 FALSE
, /* partial_inplace */
166 FALSE
), /* pcrel_offset */
168 /* 16 bit relocation. */
169 HOWTO (R_MIPS_16
, /* type */
171 2, /* size (0 = byte, 1 = short, 2 = long) */
173 FALSE
, /* pc_relative */
175 complain_overflow_signed
, /* complain_on_overflow */
176 bfd_elf_generic_reloc
, /* special_function */
177 "R_MIPS_16", /* name */
178 TRUE
, /* partial_inplace */
179 0x0000ffff, /* src_mask */
180 0x0000ffff, /* dst_mask */
181 FALSE
), /* pcrel_offset */
183 /* 32 bit relocation. */
184 HOWTO (R_MIPS_32
, /* type */
186 2, /* size (0 = byte, 1 = short, 2 = long) */
188 FALSE
, /* pc_relative */
190 complain_overflow_dont
, /* complain_on_overflow */
191 bfd_elf_generic_reloc
, /* special_function */
192 "R_MIPS_32", /* name */
193 TRUE
, /* partial_inplace */
194 0xffffffff, /* src_mask */
195 0xffffffff, /* dst_mask */
196 FALSE
), /* pcrel_offset */
198 /* 32 bit symbol relative relocation. */
199 HOWTO (R_MIPS_REL32
, /* type */
201 2, /* size (0 = byte, 1 = short, 2 = long) */
203 FALSE
, /* pc_relative */
205 complain_overflow_dont
, /* complain_on_overflow */
206 bfd_elf_generic_reloc
, /* special_function */
207 "R_MIPS_REL32", /* name */
208 TRUE
, /* partial_inplace */
209 0xffffffff, /* src_mask */
210 0xffffffff, /* dst_mask */
211 FALSE
), /* pcrel_offset */
213 /* 26 bit jump address. */
214 HOWTO (R_MIPS_26
, /* type */
216 2, /* size (0 = byte, 1 = short, 2 = long) */
218 FALSE
, /* pc_relative */
220 complain_overflow_dont
, /* complain_on_overflow */
221 /* This needs complex overflow
222 detection, because the upper 36
223 bits must match the PC + 4. */
224 bfd_elf_generic_reloc
, /* special_function */
225 "R_MIPS_26", /* name */
226 TRUE
, /* partial_inplace */
227 0x03ffffff, /* src_mask */
228 0x03ffffff, /* dst_mask */
229 FALSE
), /* pcrel_offset */
231 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
232 However, the native IRIX6 tools use them, so we try our best. */
234 /* High 16 bits of symbol value. */
235 HOWTO (R_MIPS_HI16
, /* type */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
239 FALSE
, /* pc_relative */
241 complain_overflow_dont
, /* complain_on_overflow */
242 mips_elf64_hi16_reloc
, /* special_function */
243 "R_MIPS_HI16", /* name */
244 TRUE
, /* partial_inplace */
245 0x0000ffff, /* src_mask */
246 0x0000ffff, /* dst_mask */
247 FALSE
), /* pcrel_offset */
249 /* Low 16 bits of symbol value. */
250 HOWTO (R_MIPS_LO16
, /* type */
252 2, /* size (0 = byte, 1 = short, 2 = long) */
254 FALSE
, /* pc_relative */
256 complain_overflow_dont
, /* complain_on_overflow */
257 bfd_elf_generic_reloc
, /* special_function */
258 "R_MIPS_LO16", /* name */
259 TRUE
, /* partial_inplace */
260 0x0000ffff, /* src_mask */
261 0x0000ffff, /* dst_mask */
262 FALSE
), /* pcrel_offset */
264 /* GP relative reference. */
265 HOWTO (R_MIPS_GPREL16
, /* type */
267 2, /* size (0 = byte, 1 = short, 2 = long) */
269 FALSE
, /* pc_relative */
271 complain_overflow_signed
, /* complain_on_overflow */
272 mips_elf64_gprel16_reloc
, /* special_function */
273 "R_MIPS_GPREL16", /* name */
274 TRUE
, /* partial_inplace */
275 0x0000ffff, /* src_mask */
276 0x0000ffff, /* dst_mask */
277 FALSE
), /* pcrel_offset */
279 /* Reference to literal section. */
280 HOWTO (R_MIPS_LITERAL
, /* type */
282 2, /* size (0 = byte, 1 = short, 2 = long) */
284 FALSE
, /* pc_relative */
286 complain_overflow_signed
, /* complain_on_overflow */
287 mips_elf64_literal_reloc
, /* special_function */
288 "R_MIPS_LITERAL", /* name */
289 TRUE
, /* partial_inplace */
290 0x0000ffff, /* src_mask */
291 0x0000ffff, /* dst_mask */
292 FALSE
), /* pcrel_offset */
294 /* Reference to global offset table. */
295 HOWTO (R_MIPS_GOT16
, /* type */
297 2, /* size (0 = byte, 1 = short, 2 = long) */
299 FALSE
, /* pc_relative */
301 complain_overflow_signed
, /* complain_on_overflow */
302 mips_elf64_got16_reloc
, /* special_function */
303 "R_MIPS_GOT16", /* name */
304 TRUE
, /* partial_inplace */
305 0x0000ffff, /* src_mask */
306 0x0000ffff, /* dst_mask */
307 FALSE
), /* pcrel_offset */
309 /* 16 bit PC relative reference. Note that the ABI document has a typo
310 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
311 We do the right thing here. */
312 HOWTO (R_MIPS_PC16
, /* type */
314 2, /* size (0 = byte, 1 = short, 2 = long) */
316 TRUE
, /* pc_relative */
318 complain_overflow_signed
, /* complain_on_overflow */
319 bfd_elf_generic_reloc
, /* special_function */
320 "R_MIPS_PC16", /* name */
321 TRUE
, /* partial_inplace */
322 0x0000ffff, /* src_mask */
323 0x0000ffff, /* dst_mask */
324 TRUE
), /* pcrel_offset */
326 /* 16 bit call through global offset table. */
327 HOWTO (R_MIPS_CALL16
, /* type */
329 2, /* size (0 = byte, 1 = short, 2 = long) */
331 FALSE
, /* pc_relative */
333 complain_overflow_signed
, /* complain_on_overflow */
334 bfd_elf_generic_reloc
, /* special_function */
335 "R_MIPS_CALL16", /* name */
336 TRUE
, /* partial_inplace */
337 0x0000ffff, /* src_mask */
338 0x0000ffff, /* dst_mask */
339 FALSE
), /* pcrel_offset */
341 /* 32 bit GP relative reference. */
342 HOWTO (R_MIPS_GPREL32
, /* type */
344 2, /* size (0 = byte, 1 = short, 2 = long) */
346 FALSE
, /* pc_relative */
348 complain_overflow_dont
, /* complain_on_overflow */
349 mips_elf64_gprel32_reloc
, /* special_function */
350 "R_MIPS_GPREL32", /* name */
351 TRUE
, /* partial_inplace */
352 0xffffffff, /* src_mask */
353 0xffffffff, /* dst_mask */
354 FALSE
), /* pcrel_offset */
360 /* A 5 bit shift field. */
361 HOWTO (R_MIPS_SHIFT5
, /* type */
363 2, /* size (0 = byte, 1 = short, 2 = long) */
365 FALSE
, /* pc_relative */
367 complain_overflow_bitfield
, /* complain_on_overflow */
368 bfd_elf_generic_reloc
, /* special_function */
369 "R_MIPS_SHIFT5", /* name */
370 TRUE
, /* partial_inplace */
371 0x000007c0, /* src_mask */
372 0x000007c0, /* dst_mask */
373 FALSE
), /* pcrel_offset */
375 /* A 6 bit shift field. */
376 HOWTO (R_MIPS_SHIFT6
, /* type */
378 2, /* size (0 = byte, 1 = short, 2 = long) */
380 FALSE
, /* pc_relative */
382 complain_overflow_bitfield
, /* complain_on_overflow */
383 mips_elf64_shift6_reloc
, /* special_function */
384 "R_MIPS_SHIFT6", /* name */
385 TRUE
, /* partial_inplace */
386 0x000007c4, /* src_mask */
387 0x000007c4, /* dst_mask */
388 FALSE
), /* pcrel_offset */
390 /* 64 bit relocation. */
391 HOWTO (R_MIPS_64
, /* type */
393 4, /* size (0 = byte, 1 = short, 2 = long) */
395 FALSE
, /* pc_relative */
397 complain_overflow_dont
, /* complain_on_overflow */
398 bfd_elf_generic_reloc
, /* special_function */
399 "R_MIPS_64", /* name */
400 TRUE
, /* partial_inplace */
401 MINUS_ONE
, /* src_mask */
402 MINUS_ONE
, /* dst_mask */
403 FALSE
), /* pcrel_offset */
405 /* Displacement in the global offset table. */
406 HOWTO (R_MIPS_GOT_DISP
, /* type */
408 2, /* size (0 = byte, 1 = short, 2 = long) */
410 FALSE
, /* pc_relative */
412 complain_overflow_signed
, /* complain_on_overflow */
413 bfd_elf_generic_reloc
, /* special_function */
414 "R_MIPS_GOT_DISP", /* name */
415 TRUE
, /* partial_inplace */
416 0x0000ffff, /* src_mask */
417 0x0000ffff, /* dst_mask */
418 FALSE
), /* pcrel_offset */
420 /* Displacement to page pointer in the global offset table. */
421 HOWTO (R_MIPS_GOT_PAGE
, /* type */
423 2, /* size (0 = byte, 1 = short, 2 = long) */
425 FALSE
, /* pc_relative */
427 complain_overflow_signed
, /* complain_on_overflow */
428 bfd_elf_generic_reloc
, /* special_function */
429 "R_MIPS_GOT_PAGE", /* name */
430 TRUE
, /* partial_inplace */
431 0x0000ffff, /* src_mask */
432 0x0000ffff, /* dst_mask */
433 FALSE
), /* pcrel_offset */
435 /* Offset from page pointer in the global offset table. */
436 HOWTO (R_MIPS_GOT_OFST
, /* type */
438 2, /* size (0 = byte, 1 = short, 2 = long) */
440 FALSE
, /* pc_relative */
442 complain_overflow_signed
, /* complain_on_overflow */
443 bfd_elf_generic_reloc
, /* special_function */
444 "R_MIPS_GOT_OFST", /* name */
445 TRUE
, /* partial_inplace */
446 0x0000ffff, /* src_mask */
447 0x0000ffff, /* dst_mask */
448 FALSE
), /* pcrel_offset */
450 /* High 16 bits of displacement in global offset table. */
451 HOWTO (R_MIPS_GOT_HI16
, /* type */
453 2, /* size (0 = byte, 1 = short, 2 = long) */
455 FALSE
, /* pc_relative */
457 complain_overflow_dont
, /* complain_on_overflow */
458 bfd_elf_generic_reloc
, /* special_function */
459 "R_MIPS_GOT_HI16", /* name */
460 TRUE
, /* partial_inplace */
461 0x0000ffff, /* src_mask */
462 0x0000ffff, /* dst_mask */
463 FALSE
), /* pcrel_offset */
465 /* Low 16 bits of displacement in global offset table. */
466 HOWTO (R_MIPS_GOT_LO16
, /* type */
468 2, /* size (0 = byte, 1 = short, 2 = long) */
470 FALSE
, /* pc_relative */
472 complain_overflow_dont
, /* complain_on_overflow */
473 bfd_elf_generic_reloc
, /* special_function */
474 "R_MIPS_GOT_LO16", /* name */
475 TRUE
, /* partial_inplace */
476 0x0000ffff, /* src_mask */
477 0x0000ffff, /* dst_mask */
478 FALSE
), /* pcrel_offset */
480 /* 64 bit substraction. */
481 HOWTO (R_MIPS_SUB
, /* type */
483 4, /* size (0 = byte, 1 = short, 2 = long) */
485 FALSE
, /* pc_relative */
487 complain_overflow_dont
, /* complain_on_overflow */
488 bfd_elf_generic_reloc
, /* special_function */
489 "R_MIPS_SUB", /* name */
490 TRUE
, /* partial_inplace */
491 MINUS_ONE
, /* src_mask */
492 MINUS_ONE
, /* dst_mask */
493 FALSE
), /* pcrel_offset */
495 /* Insert the addend as an instruction. */
496 /* FIXME: Not handled correctly. */
497 HOWTO (R_MIPS_INSERT_A
, /* type */
499 2, /* size (0 = byte, 1 = short, 2 = long) */
501 FALSE
, /* pc_relative */
503 complain_overflow_dont
, /* complain_on_overflow */
504 bfd_elf_generic_reloc
, /* special_function */
505 "R_MIPS_INSERT_A", /* name */
506 TRUE
, /* partial_inplace */
507 0xffffffff, /* src_mask */
508 0xffffffff, /* dst_mask */
509 FALSE
), /* pcrel_offset */
511 /* Insert the addend as an instruction, and change all relocations
512 to refer to the old instruction at the address. */
513 /* FIXME: Not handled correctly. */
514 HOWTO (R_MIPS_INSERT_B
, /* type */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
518 FALSE
, /* pc_relative */
520 complain_overflow_dont
, /* complain_on_overflow */
521 bfd_elf_generic_reloc
, /* special_function */
522 "R_MIPS_INSERT_B", /* name */
523 TRUE
, /* partial_inplace */
524 0xffffffff, /* src_mask */
525 0xffffffff, /* dst_mask */
526 FALSE
), /* pcrel_offset */
528 /* Delete a 32 bit instruction. */
529 /* FIXME: Not handled correctly. */
530 HOWTO (R_MIPS_DELETE
, /* type */
532 2, /* size (0 = byte, 1 = short, 2 = long) */
534 FALSE
, /* pc_relative */
536 complain_overflow_dont
, /* complain_on_overflow */
537 bfd_elf_generic_reloc
, /* special_function */
538 "R_MIPS_DELETE", /* name */
539 TRUE
, /* partial_inplace */
540 0xffffffff, /* src_mask */
541 0xffffffff, /* dst_mask */
542 FALSE
), /* pcrel_offset */
544 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
546 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
547 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
549 b) No other NewABI toolchain actually emits such relocations. */
550 EMPTY_HOWTO (R_MIPS_HIGHER
),
551 EMPTY_HOWTO (R_MIPS_HIGHEST
),
553 /* High 16 bits of displacement in global offset table. */
554 HOWTO (R_MIPS_CALL_HI16
, /* type */
556 2, /* size (0 = byte, 1 = short, 2 = long) */
558 FALSE
, /* pc_relative */
560 complain_overflow_dont
, /* complain_on_overflow */
561 bfd_elf_generic_reloc
, /* special_function */
562 "R_MIPS_CALL_HI16", /* name */
563 TRUE
, /* partial_inplace */
564 0x0000ffff, /* src_mask */
565 0x0000ffff, /* dst_mask */
566 FALSE
), /* pcrel_offset */
568 /* Low 16 bits of displacement in global offset table. */
569 HOWTO (R_MIPS_CALL_LO16
, /* type */
571 2, /* size (0 = byte, 1 = short, 2 = long) */
573 FALSE
, /* pc_relative */
575 complain_overflow_dont
, /* complain_on_overflow */
576 bfd_elf_generic_reloc
, /* special_function */
577 "R_MIPS_CALL_LO16", /* name */
578 TRUE
, /* partial_inplace */
579 0x0000ffff, /* src_mask */
580 0x0000ffff, /* dst_mask */
581 FALSE
), /* pcrel_offset */
583 /* Section displacement, used by an associated event location section. */
584 HOWTO (R_MIPS_SCN_DISP
, /* type */
586 2, /* size (0 = byte, 1 = short, 2 = long) */
588 FALSE
, /* pc_relative */
590 complain_overflow_dont
, /* complain_on_overflow */
591 bfd_elf_generic_reloc
, /* special_function */
592 "R_MIPS_SCN_DISP", /* name */
593 TRUE
, /* partial_inplace */
594 0xffffffff, /* src_mask */
595 0xffffffff, /* dst_mask */
596 FALSE
), /* pcrel_offset */
598 HOWTO (R_MIPS_REL16
, /* type */
600 1, /* size (0 = byte, 1 = short, 2 = long) */
602 FALSE
, /* pc_relative */
604 complain_overflow_signed
, /* complain_on_overflow */
605 bfd_elf_generic_reloc
, /* special_function */
606 "R_MIPS_REL16", /* name */
607 TRUE
, /* partial_inplace */
608 0xffff, /* src_mask */
609 0xffff, /* dst_mask */
610 FALSE
), /* pcrel_offset */
612 /* These two are obsolete. */
613 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
614 EMPTY_HOWTO (R_MIPS_PJUMP
),
616 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
617 It must be used for multigot GOT's (and only there). */
618 HOWTO (R_MIPS_RELGOT
, /* type */
620 2, /* size (0 = byte, 1 = short, 2 = long) */
622 FALSE
, /* pc_relative */
624 complain_overflow_dont
, /* complain_on_overflow */
625 bfd_elf_generic_reloc
, /* special_function */
626 "R_MIPS_RELGOT", /* name */
627 TRUE
, /* partial_inplace */
628 0xffffffff, /* src_mask */
629 0xffffffff, /* dst_mask */
630 FALSE
), /* pcrel_offset */
632 /* Protected jump conversion. This is an optimization hint. No
633 relocation is required for correctness. */
634 HOWTO (R_MIPS_JALR
, /* type */
636 2, /* size (0 = byte, 1 = short, 2 = long) */
638 FALSE
, /* pc_relative */
640 complain_overflow_dont
, /* complain_on_overflow */
641 bfd_elf_generic_reloc
, /* special_function */
642 "R_MIPS_JALR", /* name */
643 FALSE
, /* partial_inplace */
645 0x00000000, /* dst_mask */
646 FALSE
), /* pcrel_offset */
649 /* The relocation table used for SHT_RELA sections. */
651 static reloc_howto_type mips_elf64_howto_table_rela
[] =
654 HOWTO (R_MIPS_NONE
, /* type */
656 0, /* size (0 = byte, 1 = short, 2 = long) */
658 FALSE
, /* pc_relative */
660 complain_overflow_dont
, /* complain_on_overflow */
661 bfd_elf_generic_reloc
, /* special_function */
662 "R_MIPS_NONE", /* name */
663 FALSE
, /* partial_inplace */
666 FALSE
), /* pcrel_offset */
668 /* 16 bit relocation. */
669 HOWTO (R_MIPS_16
, /* type */
671 2, /* size (0 = byte, 1 = short, 2 = long) */
673 FALSE
, /* pc_relative */
675 complain_overflow_signed
, /* complain_on_overflow */
676 bfd_elf_generic_reloc
, /* special_function */
677 "R_MIPS_16", /* name */
678 FALSE
, /* partial_inplace */
680 0x0000ffff, /* dst_mask */
681 FALSE
), /* pcrel_offset */
683 /* 32 bit relocation. */
684 HOWTO (R_MIPS_32
, /* type */
686 2, /* size (0 = byte, 1 = short, 2 = long) */
688 FALSE
, /* pc_relative */
690 complain_overflow_dont
, /* complain_on_overflow */
691 bfd_elf_generic_reloc
, /* special_function */
692 "R_MIPS_32", /* name */
693 FALSE
, /* partial_inplace */
695 0xffffffff, /* dst_mask */
696 FALSE
), /* pcrel_offset */
698 /* 32 bit symbol relative relocation. */
699 HOWTO (R_MIPS_REL32
, /* type */
701 2, /* size (0 = byte, 1 = short, 2 = long) */
703 FALSE
, /* pc_relative */
705 complain_overflow_dont
, /* complain_on_overflow */
706 bfd_elf_generic_reloc
, /* special_function */
707 "R_MIPS_REL32", /* name */
708 FALSE
, /* partial_inplace */
710 0xffffffff, /* dst_mask */
711 FALSE
), /* pcrel_offset */
713 /* 26 bit jump address. */
714 HOWTO (R_MIPS_26
, /* type */
716 2, /* size (0 = byte, 1 = short, 2 = long) */
718 FALSE
, /* pc_relative */
720 complain_overflow_dont
, /* complain_on_overflow */
721 /* This needs complex overflow
722 detection, because the upper 36
723 bits must match the PC + 4. */
724 bfd_elf_generic_reloc
, /* special_function */
725 "R_MIPS_26", /* name */
726 FALSE
, /* partial_inplace */
728 0x03ffffff, /* dst_mask */
729 FALSE
), /* pcrel_offset */
731 /* High 16 bits of symbol value. */
732 HOWTO (R_MIPS_HI16
, /* type */
734 2, /* size (0 = byte, 1 = short, 2 = long) */
736 FALSE
, /* pc_relative */
738 complain_overflow_dont
, /* complain_on_overflow */
739 bfd_elf_generic_reloc
, /* special_function */
740 "R_MIPS_HI16", /* name */
741 FALSE
, /* partial_inplace */
743 0x0000ffff, /* dst_mask */
744 FALSE
), /* pcrel_offset */
746 /* Low 16 bits of symbol value. */
747 HOWTO (R_MIPS_LO16
, /* type */
749 2, /* size (0 = byte, 1 = short, 2 = long) */
751 FALSE
, /* pc_relative */
753 complain_overflow_dont
, /* complain_on_overflow */
754 bfd_elf_generic_reloc
, /* special_function */
755 "R_MIPS_LO16", /* name */
756 FALSE
, /* partial_inplace */
758 0x0000ffff, /* dst_mask */
759 FALSE
), /* pcrel_offset */
761 /* GP relative reference. */
762 HOWTO (R_MIPS_GPREL16
, /* type */
764 2, /* size (0 = byte, 1 = short, 2 = long) */
766 FALSE
, /* pc_relative */
768 complain_overflow_signed
, /* complain_on_overflow */
769 mips_elf64_gprel16_reloc
, /* special_function */
770 "R_MIPS_GPREL16", /* name */
771 FALSE
, /* partial_inplace */
773 0x0000ffff, /* dst_mask */
774 FALSE
), /* pcrel_offset */
776 /* Reference to literal section. */
777 HOWTO (R_MIPS_LITERAL
, /* type */
779 2, /* size (0 = byte, 1 = short, 2 = long) */
781 FALSE
, /* pc_relative */
783 complain_overflow_signed
, /* complain_on_overflow */
784 mips_elf64_literal_reloc
, /* special_function */
785 "R_MIPS_LITERAL", /* name */
786 FALSE
, /* partial_inplace */
788 0x0000ffff, /* dst_mask */
789 FALSE
), /* pcrel_offset */
791 /* Reference to global offset table. */
792 HOWTO (R_MIPS_GOT16
, /* type */
794 2, /* size (0 = byte, 1 = short, 2 = long) */
796 FALSE
, /* pc_relative */
798 complain_overflow_signed
, /* complain_on_overflow */
799 mips_elf64_got16_reloc
, /* special_function */
800 "R_MIPS_GOT16", /* name */
801 FALSE
, /* partial_inplace */
803 0x0000ffff, /* dst_mask */
804 FALSE
), /* pcrel_offset */
806 /* 16 bit PC relative reference. Note that the ABI document has a typo
807 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
808 We do the right thing here. */
809 HOWTO (R_MIPS_PC16
, /* type */
811 2, /* size (0 = byte, 1 = short, 2 = long) */
813 TRUE
, /* pc_relative */
815 complain_overflow_signed
, /* complain_on_overflow */
816 bfd_elf_generic_reloc
, /* special_function */
817 "R_MIPS_PC16", /* name */
818 FALSE
, /* partial_inplace */
820 0x0000ffff, /* dst_mask */
821 TRUE
), /* pcrel_offset */
823 /* 16 bit call through global offset table. */
824 HOWTO (R_MIPS_CALL16
, /* type */
826 2, /* size (0 = byte, 1 = short, 2 = long) */
828 FALSE
, /* pc_relative */
830 complain_overflow_signed
, /* complain_on_overflow */
831 bfd_elf_generic_reloc
, /* special_function */
832 "R_MIPS_CALL16", /* name */
833 FALSE
, /* partial_inplace */
835 0x0000ffff, /* dst_mask */
836 FALSE
), /* pcrel_offset */
838 /* 32 bit GP relative reference. */
839 HOWTO (R_MIPS_GPREL32
, /* type */
841 2, /* size (0 = byte, 1 = short, 2 = long) */
843 FALSE
, /* pc_relative */
845 complain_overflow_dont
, /* complain_on_overflow */
846 mips_elf64_gprel32_reloc
, /* special_function */
847 "R_MIPS_GPREL32", /* name */
848 FALSE
, /* partial_inplace */
850 0xffffffff, /* dst_mask */
851 FALSE
), /* pcrel_offset */
857 /* A 5 bit shift field. */
858 HOWTO (R_MIPS_SHIFT5
, /* type */
860 2, /* size (0 = byte, 1 = short, 2 = long) */
862 FALSE
, /* pc_relative */
864 complain_overflow_bitfield
, /* complain_on_overflow */
865 bfd_elf_generic_reloc
, /* special_function */
866 "R_MIPS_SHIFT5", /* name */
867 FALSE
, /* partial_inplace */
869 0x000007c0, /* dst_mask */
870 FALSE
), /* pcrel_offset */
872 /* A 6 bit shift field. */
873 HOWTO (R_MIPS_SHIFT6
, /* type */
875 2, /* size (0 = byte, 1 = short, 2 = long) */
877 FALSE
, /* pc_relative */
879 complain_overflow_bitfield
, /* complain_on_overflow */
880 mips_elf64_shift6_reloc
, /* special_function */
881 "R_MIPS_SHIFT6", /* name */
882 FALSE
, /* partial_inplace */
884 0x000007c4, /* dst_mask */
885 FALSE
), /* pcrel_offset */
887 /* 64 bit relocation. */
888 HOWTO (R_MIPS_64
, /* type */
890 4, /* size (0 = byte, 1 = short, 2 = long) */
892 FALSE
, /* pc_relative */
894 complain_overflow_dont
, /* complain_on_overflow */
895 bfd_elf_generic_reloc
, /* special_function */
896 "R_MIPS_64", /* name */
897 FALSE
, /* partial_inplace */
899 MINUS_ONE
, /* dst_mask */
900 FALSE
), /* pcrel_offset */
902 /* Displacement in the global offset table. */
903 HOWTO (R_MIPS_GOT_DISP
, /* type */
905 2, /* size (0 = byte, 1 = short, 2 = long) */
907 FALSE
, /* pc_relative */
909 complain_overflow_signed
, /* complain_on_overflow */
910 bfd_elf_generic_reloc
, /* special_function */
911 "R_MIPS_GOT_DISP", /* name */
912 FALSE
, /* partial_inplace */
914 0x0000ffff, /* dst_mask */
915 FALSE
), /* pcrel_offset */
917 /* Displacement to page pointer in the global offset table. */
918 HOWTO (R_MIPS_GOT_PAGE
, /* type */
920 2, /* size (0 = byte, 1 = short, 2 = long) */
922 FALSE
, /* pc_relative */
924 complain_overflow_signed
, /* complain_on_overflow */
925 bfd_elf_generic_reloc
, /* special_function */
926 "R_MIPS_GOT_PAGE", /* name */
927 FALSE
, /* partial_inplace */
929 0x0000ffff, /* dst_mask */
930 FALSE
), /* pcrel_offset */
932 /* Offset from page pointer in the global offset table. */
933 HOWTO (R_MIPS_GOT_OFST
, /* type */
935 2, /* size (0 = byte, 1 = short, 2 = long) */
937 FALSE
, /* pc_relative */
939 complain_overflow_signed
, /* complain_on_overflow */
940 bfd_elf_generic_reloc
, /* special_function */
941 "R_MIPS_GOT_OFST", /* name */
942 FALSE
, /* partial_inplace */
944 0x0000ffff, /* dst_mask */
945 FALSE
), /* pcrel_offset */
947 /* High 16 bits of displacement in global offset table. */
948 HOWTO (R_MIPS_GOT_HI16
, /* type */
950 2, /* size (0 = byte, 1 = short, 2 = long) */
952 FALSE
, /* pc_relative */
954 complain_overflow_dont
, /* complain_on_overflow */
955 bfd_elf_generic_reloc
, /* special_function */
956 "R_MIPS_GOT_HI16", /* name */
957 FALSE
, /* partial_inplace */
959 0x0000ffff, /* dst_mask */
960 FALSE
), /* pcrel_offset */
962 /* Low 16 bits of displacement in global offset table. */
963 HOWTO (R_MIPS_GOT_LO16
, /* type */
965 2, /* size (0 = byte, 1 = short, 2 = long) */
967 FALSE
, /* pc_relative */
969 complain_overflow_dont
, /* complain_on_overflow */
970 bfd_elf_generic_reloc
, /* special_function */
971 "R_MIPS_GOT_LO16", /* name */
972 FALSE
, /* partial_inplace */
974 0x0000ffff, /* dst_mask */
975 FALSE
), /* pcrel_offset */
977 /* 64 bit substraction. */
978 HOWTO (R_MIPS_SUB
, /* type */
980 4, /* size (0 = byte, 1 = short, 2 = long) */
982 FALSE
, /* pc_relative */
984 complain_overflow_dont
, /* complain_on_overflow */
985 bfd_elf_generic_reloc
, /* special_function */
986 "R_MIPS_SUB", /* name */
987 FALSE
, /* partial_inplace */
989 MINUS_ONE
, /* dst_mask */
990 FALSE
), /* pcrel_offset */
992 /* Insert the addend as an instruction. */
993 /* FIXME: Not handled correctly. */
994 HOWTO (R_MIPS_INSERT_A
, /* type */
996 2, /* size (0 = byte, 1 = short, 2 = long) */
998 FALSE
, /* pc_relative */
1000 complain_overflow_dont
, /* complain_on_overflow */
1001 bfd_elf_generic_reloc
, /* special_function */
1002 "R_MIPS_INSERT_A", /* name */
1003 FALSE
, /* partial_inplace */
1005 0xffffffff, /* dst_mask */
1006 FALSE
), /* pcrel_offset */
1008 /* Insert the addend as an instruction, and change all relocations
1009 to refer to the old instruction at the address. */
1010 /* FIXME: Not handled correctly. */
1011 HOWTO (R_MIPS_INSERT_B
, /* type */
1013 2, /* size (0 = byte, 1 = short, 2 = long) */
1015 FALSE
, /* pc_relative */
1017 complain_overflow_dont
, /* complain_on_overflow */
1018 bfd_elf_generic_reloc
, /* special_function */
1019 "R_MIPS_INSERT_B", /* name */
1020 FALSE
, /* partial_inplace */
1022 0xffffffff, /* dst_mask */
1023 FALSE
), /* pcrel_offset */
1025 /* Delete a 32 bit instruction. */
1026 /* FIXME: Not handled correctly. */
1027 HOWTO (R_MIPS_DELETE
, /* type */
1029 2, /* size (0 = byte, 1 = short, 2 = long) */
1031 FALSE
, /* pc_relative */
1033 complain_overflow_dont
, /* complain_on_overflow */
1034 bfd_elf_generic_reloc
, /* special_function */
1035 "R_MIPS_DELETE", /* name */
1036 FALSE
, /* partial_inplace */
1038 0xffffffff, /* dst_mask */
1039 FALSE
), /* pcrel_offset */
1041 /* Get the higher value of a 64 bit addend. */
1042 HOWTO (R_MIPS_HIGHER
, /* type */
1044 2, /* size (0 = byte, 1 = short, 2 = long) */
1046 FALSE
, /* pc_relative */
1048 complain_overflow_dont
, /* complain_on_overflow */
1049 bfd_elf_generic_reloc
, /* special_function */
1050 "R_MIPS_HIGHER", /* name */
1051 FALSE
, /* partial_inplace */
1053 0x0000ffff, /* dst_mask */
1054 FALSE
), /* pcrel_offset */
1056 /* Get the highest value of a 64 bit addend. */
1057 HOWTO (R_MIPS_HIGHEST
, /* type */
1059 2, /* size (0 = byte, 1 = short, 2 = long) */
1061 FALSE
, /* pc_relative */
1063 complain_overflow_dont
, /* complain_on_overflow */
1064 bfd_elf_generic_reloc
, /* special_function */
1065 "R_MIPS_HIGHEST", /* name */
1066 FALSE
, /* partial_inplace */
1068 0x0000ffff, /* dst_mask */
1069 FALSE
), /* pcrel_offset */
1071 /* High 16 bits of displacement in global offset table. */
1072 HOWTO (R_MIPS_CALL_HI16
, /* type */
1074 2, /* size (0 = byte, 1 = short, 2 = long) */
1076 FALSE
, /* pc_relative */
1078 complain_overflow_dont
, /* complain_on_overflow */
1079 bfd_elf_generic_reloc
, /* special_function */
1080 "R_MIPS_CALL_HI16", /* name */
1081 FALSE
, /* partial_inplace */
1083 0x0000ffff, /* dst_mask */
1084 FALSE
), /* pcrel_offset */
1086 /* Low 16 bits of displacement in global offset table. */
1087 HOWTO (R_MIPS_CALL_LO16
, /* type */
1089 2, /* size (0 = byte, 1 = short, 2 = long) */
1091 FALSE
, /* pc_relative */
1093 complain_overflow_dont
, /* complain_on_overflow */
1094 bfd_elf_generic_reloc
, /* special_function */
1095 "R_MIPS_CALL_LO16", /* name */
1096 FALSE
, /* partial_inplace */
1098 0x0000ffff, /* dst_mask */
1099 FALSE
), /* pcrel_offset */
1101 /* Section displacement, used by an associated event location section. */
1102 HOWTO (R_MIPS_SCN_DISP
, /* type */
1104 2, /* size (0 = byte, 1 = short, 2 = long) */
1106 FALSE
, /* pc_relative */
1108 complain_overflow_dont
, /* complain_on_overflow */
1109 bfd_elf_generic_reloc
, /* special_function */
1110 "R_MIPS_SCN_DISP", /* name */
1111 FALSE
, /* partial_inplace */
1113 0xffffffff, /* dst_mask */
1114 FALSE
), /* pcrel_offset */
1116 HOWTO (R_MIPS_REL16
, /* type */
1118 1, /* size (0 = byte, 1 = short, 2 = long) */
1120 FALSE
, /* pc_relative */
1122 complain_overflow_signed
, /* complain_on_overflow */
1123 bfd_elf_generic_reloc
, /* special_function */
1124 "R_MIPS_REL16", /* name */
1125 FALSE
, /* partial_inplace */
1127 0xffff, /* dst_mask */
1128 FALSE
), /* pcrel_offset */
1130 /* These two are obsolete. */
1131 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
1132 EMPTY_HOWTO (R_MIPS_PJUMP
),
1134 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1135 It must be used for multigot GOT's (and only there). */
1136 HOWTO (R_MIPS_RELGOT
, /* type */
1138 2, /* size (0 = byte, 1 = short, 2 = long) */
1140 FALSE
, /* pc_relative */
1142 complain_overflow_dont
, /* complain_on_overflow */
1143 bfd_elf_generic_reloc
, /* special_function */
1144 "R_MIPS_RELGOT", /* name */
1145 FALSE
, /* partial_inplace */
1147 0xffffffff, /* dst_mask */
1148 FALSE
), /* pcrel_offset */
1150 /* Protected jump conversion. This is an optimization hint. No
1151 relocation is required for correctness. */
1152 HOWTO (R_MIPS_JALR
, /* type */
1154 2, /* size (0 = byte, 1 = short, 2 = long) */
1156 FALSE
, /* pc_relative */
1158 complain_overflow_dont
, /* complain_on_overflow */
1159 bfd_elf_generic_reloc
, /* special_function */
1160 "R_MIPS_JALR", /* name */
1161 FALSE
, /* partial_inplace */
1163 0x00000000, /* dst_mask */
1164 FALSE
), /* pcrel_offset */
1167 /* The reloc used for the mips16 jump instruction. */
1168 static reloc_howto_type elf_mips16_jump_howto
=
1169 HOWTO (R_MIPS16_26
, /* type */
1171 2, /* size (0 = byte, 1 = short, 2 = long) */
1173 FALSE
, /* pc_relative */
1175 complain_overflow_dont
, /* complain_on_overflow */
1176 /* This needs complex overflow
1177 detection, because the upper four
1178 bits must match the PC. */
1179 mips16_jump_reloc
, /* special_function */
1180 "R_MIPS16_26", /* name */
1181 TRUE
, /* partial_inplace */
1182 0x3ffffff, /* src_mask */
1183 0x3ffffff, /* dst_mask */
1184 FALSE
); /* pcrel_offset */
1186 /* The reloc used for the mips16 gprel instruction. */
1187 static reloc_howto_type elf_mips16_gprel_howto
=
1188 HOWTO (R_MIPS16_GPREL
, /* type */
1190 2, /* size (0 = byte, 1 = short, 2 = long) */
1192 FALSE
, /* pc_relative */
1194 complain_overflow_signed
, /* complain_on_overflow */
1195 mips16_gprel_reloc
, /* special_function */
1196 "R_MIPS16_GPREL", /* name */
1197 TRUE
, /* partial_inplace */
1198 0x07ff001f, /* src_mask */
1199 0x07ff001f, /* dst_mask */
1200 FALSE
); /* pcrel_offset */
1202 /* GNU extension to record C++ vtable hierarchy */
1203 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
1204 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
1206 2, /* size (0 = byte, 1 = short, 2 = long) */
1208 FALSE
, /* pc_relative */
1210 complain_overflow_dont
, /* complain_on_overflow */
1211 NULL
, /* special_function */
1212 "R_MIPS_GNU_VTINHERIT", /* name */
1213 FALSE
, /* partial_inplace */
1216 FALSE
); /* pcrel_offset */
1218 /* GNU extension to record C++ vtable member usage */
1219 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
1220 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
1222 2, /* size (0 = byte, 1 = short, 2 = long) */
1224 FALSE
, /* pc_relative */
1226 complain_overflow_dont
, /* complain_on_overflow */
1227 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
1228 "R_MIPS_GNU_VTENTRY", /* name */
1229 FALSE
, /* partial_inplace */
1232 FALSE
); /* pcrel_offset */
1234 /* Swap in a MIPS 64-bit Rel reloc. */
1237 mips_elf64_swap_reloc_in (abfd
, src
, dst
)
1239 const Elf64_Mips_External_Rel
*src
;
1240 Elf64_Mips_Internal_Rela
*dst
;
1242 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1243 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1244 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1245 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1246 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1247 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1251 /* Swap in a MIPS 64-bit Rela reloc. */
1254 mips_elf64_swap_reloca_in (abfd
, src
, dst
)
1256 const Elf64_Mips_External_Rela
*src
;
1257 Elf64_Mips_Internal_Rela
*dst
;
1259 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1260 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1261 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1262 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1263 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1264 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1265 dst
->r_addend
= H_GET_S64 (abfd
, src
->r_addend
);
1268 /* Swap out a MIPS 64-bit Rel reloc. */
1271 mips_elf64_swap_reloc_out (abfd
, src
, dst
)
1273 const Elf64_Mips_Internal_Rela
*src
;
1274 Elf64_Mips_External_Rel
*dst
;
1276 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1277 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1278 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1279 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1280 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1281 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1284 /* Swap out a MIPS 64-bit Rela reloc. */
1287 mips_elf64_swap_reloca_out (abfd
, src
, dst
)
1289 const Elf64_Mips_Internal_Rela
*src
;
1290 Elf64_Mips_External_Rela
*dst
;
1292 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1293 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1294 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1295 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1296 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1297 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1298 H_PUT_S64 (abfd
, src
->r_addend
, dst
->r_addend
);
1301 /* Swap in a MIPS 64-bit Rel reloc. */
1304 mips_elf64_be_swap_reloc_in (abfd
, src
, dst
)
1306 const bfd_byte
*src
;
1307 Elf_Internal_Rela
*dst
;
1309 Elf64_Mips_Internal_Rela mirel
;
1311 mips_elf64_swap_reloc_in (abfd
,
1312 (const Elf64_Mips_External_Rel
*) src
,
1315 dst
[0].r_offset
= mirel
.r_offset
;
1316 dst
[0].r_info
= ELF64_R_INFO (mirel
.r_sym
, mirel
.r_type
);
1317 dst
[0].r_addend
= 0;
1318 dst
[1].r_offset
= mirel
.r_offset
;
1319 dst
[1].r_info
= ELF64_R_INFO (mirel
.r_ssym
, mirel
.r_type2
);
1320 dst
[1].r_addend
= 0;
1321 dst
[2].r_offset
= mirel
.r_offset
;
1322 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirel
.r_type3
);
1323 dst
[2].r_addend
= 0;
1326 /* Swap in a MIPS 64-bit Rela reloc. */
1329 mips_elf64_be_swap_reloca_in (abfd
, src
, dst
)
1331 const bfd_byte
*src
;
1332 Elf_Internal_Rela
*dst
;
1334 Elf64_Mips_Internal_Rela mirela
;
1336 mips_elf64_swap_reloca_in (abfd
,
1337 (const Elf64_Mips_External_Rela
*) src
,
1340 dst
[0].r_offset
= mirela
.r_offset
;
1341 dst
[0].r_info
= ELF64_R_INFO (mirela
.r_sym
, mirela
.r_type
);
1342 dst
[0].r_addend
= mirela
.r_addend
;
1343 dst
[1].r_offset
= mirela
.r_offset
;
1344 dst
[1].r_info
= ELF64_R_INFO (mirela
.r_ssym
, mirela
.r_type2
);
1345 dst
[1].r_addend
= 0;
1346 dst
[2].r_offset
= mirela
.r_offset
;
1347 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirela
.r_type3
);
1348 dst
[2].r_addend
= 0;
1351 /* Swap out a MIPS 64-bit Rel reloc. */
1354 mips_elf64_be_swap_reloc_out (abfd
, src
, dst
)
1356 const Elf_Internal_Rela
*src
;
1359 Elf64_Mips_Internal_Rela mirel
;
1361 mirel
.r_offset
= src
[0].r_offset
;
1362 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1364 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1367 mirel
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1368 mirel
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1369 mirel
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1370 mirel
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1371 mirel
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1373 mips_elf64_swap_reloc_out (abfd
, &mirel
,
1374 (Elf64_Mips_External_Rel
*) dst
);
1377 /* Swap out a MIPS 64-bit Rela reloc. */
1380 mips_elf64_be_swap_reloca_out (abfd
, src
, dst
)
1382 const Elf_Internal_Rela
*src
;
1385 Elf64_Mips_Internal_Rela mirela
;
1387 mirela
.r_offset
= src
[0].r_offset
;
1388 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1389 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1391 mirela
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1392 mirela
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1393 mirela
.r_addend
= src
[0].r_addend
;
1394 BFD_ASSERT(src
[1].r_addend
== 0);
1395 BFD_ASSERT(src
[2].r_addend
== 0);
1397 mirela
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1398 mirela
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1399 mirela
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1401 mips_elf64_swap_reloca_out (abfd
, &mirela
,
1402 (Elf64_Mips_External_Rela
*) dst
);
1405 /* Do a R_MIPS_HI16 relocation. */
1407 static bfd_reloc_status_type
1408 mips_elf64_hi16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1409 output_bfd
, error_message
)
1410 bfd
*abfd ATTRIBUTE_UNUSED
;
1411 arelent
*reloc_entry
;
1413 PTR data ATTRIBUTE_UNUSED
;
1414 asection
*input_section
;
1416 char **error_message ATTRIBUTE_UNUSED
;
1418 /* If we're relocating, and this is an external symbol, we don't
1419 want to change anything. */
1420 if (output_bfd
!= (bfd
*) NULL
1421 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1422 && (! reloc_entry
->howto
->partial_inplace
1423 || reloc_entry
->addend
== 0))
1425 reloc_entry
->address
+= input_section
->output_offset
;
1426 return bfd_reloc_ok
;
1429 if (((reloc_entry
->addend
& 0xffff) + 0x8000) & ~0xffff)
1430 reloc_entry
->addend
+= 0x8000;
1432 return bfd_reloc_continue
;
1435 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1436 table used for PIC code. If the symbol is an external symbol, the
1437 instruction is modified to contain the offset of the appropriate
1438 entry in the global offset table. If the symbol is a section
1439 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1440 addends are combined to form the real addend against the section
1441 symbol; the GOT16 is modified to contain the offset of an entry in
1442 the global offset table, and the LO16 is modified to offset it
1443 appropriately. Thus an offset larger than 16 bits requires a
1444 modified value in the global offset table.
1446 This implementation suffices for the assembler, but the linker does
1447 not yet know how to create global offset tables. */
1449 static bfd_reloc_status_type
1450 mips_elf64_got16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1451 output_bfd
, error_message
)
1453 arelent
*reloc_entry
;
1456 asection
*input_section
;
1458 char **error_message
;
1460 /* If we're relocating, and this is a local symbol, we can handle it
1461 just like an R_MIPS_HI16. */
1462 if (output_bfd
!= (bfd
*) NULL
1463 && (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1464 return mips_elf64_hi16_reloc (abfd
, reloc_entry
, symbol
, data
,
1465 input_section
, output_bfd
, error_message
);
1468 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1469 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
1470 input_section
, output_bfd
, error_message
);
1473 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1474 dangerous relocation. */
1477 mips_elf64_assign_gp (output_bfd
, pgp
)
1485 /* If we've already figured out what GP will be, just return it. */
1486 *pgp
= _bfd_get_gp_value (output_bfd
);
1490 count
= bfd_get_symcount (output_bfd
);
1491 sym
= bfd_get_outsymbols (output_bfd
);
1493 /* The linker script will have created a symbol named `_gp' with the
1494 appropriate value. */
1495 if (sym
== (asymbol
**) NULL
)
1499 for (i
= 0; i
< count
; i
++, sym
++)
1501 register const char *name
;
1503 name
= bfd_asymbol_name (*sym
);
1504 if (*name
== '_' && strcmp (name
, "_gp") == 0)
1506 *pgp
= bfd_asymbol_value (*sym
);
1507 _bfd_set_gp_value (output_bfd
, *pgp
);
1515 /* Only get the error once. */
1517 _bfd_set_gp_value (output_bfd
, *pgp
);
1524 /* We have to figure out the gp value, so that we can adjust the
1525 symbol value correctly. We look up the symbol _gp in the output
1526 BFD. If we can't find it, we're stuck. We cache it in the ELF
1527 target data. We don't need to adjust the symbol value for an
1528 external symbol if we are producing relocateable output. */
1530 static bfd_reloc_status_type
1531 mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
, pgp
)
1534 bfd_boolean relocateable
;
1535 char **error_message
;
1538 if (bfd_is_und_section (symbol
->section
)
1542 return bfd_reloc_undefined
;
1545 *pgp
= _bfd_get_gp_value (output_bfd
);
1548 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
1552 /* Make up a value. */
1553 *pgp
= symbol
->section
->output_section
->vma
/*+ 0x4000*/;
1554 _bfd_set_gp_value (output_bfd
, *pgp
);
1556 else if (!mips_elf64_assign_gp (output_bfd
, pgp
))
1559 (char *) _("GP relative relocation when _gp not defined");
1560 return bfd_reloc_dangerous
;
1564 return bfd_reloc_ok
;
1567 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1568 become the offset from the gp register. */
1570 static bfd_reloc_status_type
1571 mips_elf64_gprel16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1572 output_bfd
, error_message
)
1574 arelent
*reloc_entry
;
1577 asection
*input_section
;
1579 char **error_message
;
1581 bfd_boolean relocateable
;
1582 bfd_reloc_status_type ret
;
1585 /* If we're relocating, and this is an external symbol with no
1586 addend, we don't want to change anything. We will only have an
1587 addend if this is a newly created reloc, not read from an ELF
1589 if (output_bfd
!= (bfd
*) NULL
1590 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1591 && (! reloc_entry
->howto
->partial_inplace
1592 || reloc_entry
->addend
== 0))
1594 reloc_entry
->address
+= input_section
->output_offset
;
1595 return bfd_reloc_ok
;
1598 if (output_bfd
!= (bfd
*) NULL
)
1599 relocateable
= TRUE
;
1602 relocateable
= FALSE
;
1603 output_bfd
= symbol
->section
->output_section
->owner
;
1606 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1608 if (ret
!= bfd_reloc_ok
)
1611 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1612 input_section
, relocateable
,
1616 /* Do a R_MIPS_LITERAL relocation. */
1618 static bfd_reloc_status_type
1619 mips_elf64_literal_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1620 output_bfd
, error_message
)
1622 arelent
*reloc_entry
;
1625 asection
*input_section
;
1627 char **error_message
;
1629 bfd_boolean relocateable
;
1630 bfd_reloc_status_type ret
;
1633 /* If we're relocating, and this is an external symbol, we don't
1634 want to change anything. */
1635 if (output_bfd
!= (bfd
*) NULL
1636 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1637 && (! reloc_entry
->howto
->partial_inplace
1638 || reloc_entry
->addend
== 0))
1640 reloc_entry
->address
+= input_section
->output_offset
;
1641 return bfd_reloc_ok
;
1644 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1645 if (output_bfd
!= (bfd
*) NULL
)
1646 relocateable
= TRUE
;
1649 relocateable
= FALSE
;
1650 output_bfd
= symbol
->section
->output_section
->owner
;
1653 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1655 if (ret
!= bfd_reloc_ok
)
1658 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1659 input_section
, relocateable
,
1663 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1664 become the offset from the gp register. */
1666 static bfd_reloc_status_type
1667 mips_elf64_gprel32_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1668 output_bfd
, error_message
)
1670 arelent
*reloc_entry
;
1673 asection
*input_section
;
1675 char **error_message
;
1677 bfd_boolean relocateable
;
1678 bfd_reloc_status_type ret
;
1683 /* If we're relocating, and this is an external symbol with no
1684 addend, we don't want to change anything. We will only have an
1685 addend if this is a newly created reloc, not read from an ELF
1687 if (output_bfd
!= (bfd
*) NULL
1688 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1689 && reloc_entry
->addend
== 0)
1691 *error_message
= (char *)
1692 _("32bits gp relative relocation occurs for an external symbol");
1693 return bfd_reloc_outofrange
;
1696 if (output_bfd
!= (bfd
*) NULL
)
1698 relocateable
= TRUE
;
1699 gp
= _bfd_get_gp_value (output_bfd
);
1703 relocateable
= FALSE
;
1704 output_bfd
= symbol
->section
->output_section
->owner
;
1706 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
,
1707 error_message
, &gp
);
1708 if (ret
!= bfd_reloc_ok
)
1712 if (bfd_is_com_section (symbol
->section
))
1715 relocation
= symbol
->value
;
1717 relocation
+= symbol
->section
->output_section
->vma
;
1718 relocation
+= symbol
->section
->output_offset
;
1720 if (reloc_entry
->address
> input_section
->_cooked_size
)
1721 return bfd_reloc_outofrange
;
1723 if (reloc_entry
->howto
->src_mask
== 0)
1725 /* This case arises with the 64-bit MIPS ELF ABI. */
1729 val
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1731 /* Set val to the offset into the section or symbol. */
1732 val
+= reloc_entry
->addend
;
1734 /* Adjust val for the final section location and GP value. If we
1735 are producing relocateable output, we don't want to do this for
1736 an external symbol. */
1738 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1739 val
+= relocation
- gp
;
1741 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
1744 reloc_entry
->address
+= input_section
->output_offset
;
1746 return bfd_reloc_ok
;
1749 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1750 the rest is at bits 6-10. The bitpos already got right by the howto. */
1752 static bfd_reloc_status_type
1753 mips_elf64_shift6_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1754 output_bfd
, error_message
)
1755 bfd
*abfd ATTRIBUTE_UNUSED
;
1756 arelent
*reloc_entry
;
1758 PTR data ATTRIBUTE_UNUSED
;
1759 asection
*input_section
;
1761 char **error_message ATTRIBUTE_UNUSED
;
1763 /* If we're relocating, and this is an external symbol, we don't
1764 want to change anything. */
1765 if (output_bfd
!= (bfd
*) NULL
1766 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1767 && (! reloc_entry
->howto
->partial_inplace
1768 || reloc_entry
->addend
== 0))
1770 reloc_entry
->address
+= input_section
->output_offset
;
1771 return bfd_reloc_ok
;
1774 reloc_entry
->addend
= (reloc_entry
->addend
& 0x00007c0)
1775 | (reloc_entry
->addend
& 0x00000800) >> 9;
1777 return bfd_reloc_continue
;
1780 /* Handle a mips16 jump. */
1782 static bfd_reloc_status_type
1783 mips16_jump_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1784 output_bfd
, error_message
)
1785 bfd
*abfd ATTRIBUTE_UNUSED
;
1786 arelent
*reloc_entry
;
1788 PTR data ATTRIBUTE_UNUSED
;
1789 asection
*input_section
;
1791 char **error_message ATTRIBUTE_UNUSED
;
1793 if (output_bfd
!= (bfd
*) NULL
1794 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1795 && (! reloc_entry
->howto
->partial_inplace
1796 || reloc_entry
->addend
== 0))
1798 reloc_entry
->address
+= input_section
->output_offset
;
1799 return bfd_reloc_ok
;
1804 static bfd_boolean warned
;
1807 (*_bfd_error_handler
)
1808 (_("Linking mips16 objects into %s format is not supported"),
1809 bfd_get_target (input_section
->output_section
->owner
));
1813 return bfd_reloc_undefined
;
1816 /* Handle a mips16 GP relative reloc. */
1818 static bfd_reloc_status_type
1819 mips16_gprel_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1820 output_bfd
, error_message
)
1822 arelent
*reloc_entry
;
1825 asection
*input_section
;
1827 char **error_message
;
1829 bfd_boolean relocateable
;
1830 bfd_reloc_status_type ret
;
1832 unsigned short extend
, insn
;
1833 unsigned long final
;
1835 /* If we're relocating, and this is an external symbol with no
1836 addend, we don't want to change anything. We will only have an
1837 addend if this is a newly created reloc, not read from an ELF
1839 if (output_bfd
!= NULL
1840 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1841 && reloc_entry
->addend
== 0)
1843 reloc_entry
->address
+= input_section
->output_offset
;
1844 return bfd_reloc_ok
;
1847 if (output_bfd
!= NULL
)
1848 relocateable
= TRUE
;
1851 relocateable
= FALSE
;
1852 output_bfd
= symbol
->section
->output_section
->owner
;
1855 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1857 if (ret
!= bfd_reloc_ok
)
1860 if (reloc_entry
->address
> input_section
->_cooked_size
)
1861 return bfd_reloc_outofrange
;
1863 /* Pick up the mips16 extend instruction and the real instruction. */
1864 extend
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1865 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1867 /* Stuff the current addend back as a 32 bit value, do the usual
1868 relocation, and then clean up. */
1870 (bfd_vma
) (((extend
& 0x1f) << 11)
1873 (bfd_byte
*) data
+ reloc_entry
->address
);
1875 ret
= _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1876 input_section
, relocateable
, data
, gp
);
1878 final
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1880 (bfd_vma
) ((extend
& 0xf800)
1881 | ((final
>> 11) & 0x1f)
1883 (bfd_byte
*) data
+ reloc_entry
->address
);
1885 (bfd_vma
) ((insn
& 0xffe0)
1887 (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1892 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1894 struct elf_reloc_map
{
1895 bfd_reloc_code_real_type bfd_val
;
1896 enum elf_mips_reloc_type elf_val
;
1899 static const struct elf_reloc_map mips_reloc_map
[] =
1901 { BFD_RELOC_NONE
, R_MIPS_NONE
},
1902 { BFD_RELOC_16
, R_MIPS_16
},
1903 { BFD_RELOC_32
, R_MIPS_32
},
1904 /* There is no BFD reloc for R_MIPS_REL32. */
1905 { BFD_RELOC_64
, R_MIPS_64
},
1906 { BFD_RELOC_CTOR
, R_MIPS_64
},
1907 { BFD_RELOC_16_PCREL_S2
, R_MIPS_PC16
},
1908 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
1909 { BFD_RELOC_LO16
, R_MIPS_LO16
},
1910 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
1911 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
1912 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
1913 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
1914 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
1915 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
1916 { BFD_RELOC_MIPS_SHIFT5
, R_MIPS_SHIFT5
},
1917 { BFD_RELOC_MIPS_SHIFT6
, R_MIPS_SHIFT6
},
1918 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
},
1919 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
1920 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
1921 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
1922 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
1923 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
1924 { BFD_RELOC_MIPS_INSERT_A
, R_MIPS_INSERT_A
},
1925 { BFD_RELOC_MIPS_INSERT_B
, R_MIPS_INSERT_B
},
1926 { BFD_RELOC_MIPS_DELETE
, R_MIPS_DELETE
},
1927 { BFD_RELOC_MIPS_HIGHEST
, R_MIPS_HIGHEST
},
1928 { BFD_RELOC_MIPS_HIGHER
, R_MIPS_HIGHER
},
1929 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
1930 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
1931 { BFD_RELOC_MIPS_SCN_DISP
, R_MIPS_SCN_DISP
},
1932 { BFD_RELOC_MIPS_REL16
, R_MIPS_REL16
},
1933 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1934 { BFD_RELOC_MIPS_RELGOT
, R_MIPS_RELGOT
},
1935 { BFD_RELOC_MIPS_JALR
, R_MIPS_JALR
}
1938 /* Given a BFD reloc type, return a howto structure. */
1940 static reloc_howto_type
*
1941 bfd_elf64_bfd_reloc_type_lookup (abfd
, code
)
1942 bfd
*abfd ATTRIBUTE_UNUSED
;
1943 bfd_reloc_code_real_type code
;
1946 /* FIXME: We default to RELA here instead of choosing the right
1947 relocation variant. */
1948 reloc_howto_type
*howto_table
= mips_elf64_howto_table_rela
;
1950 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
1953 if (mips_reloc_map
[i
].bfd_val
== code
)
1954 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
1959 case BFD_RELOC_MIPS16_JMP
:
1960 return &elf_mips16_jump_howto
;
1961 case BFD_RELOC_MIPS16_GPREL
:
1962 return &elf_mips16_gprel_howto
;
1963 case BFD_RELOC_VTABLE_INHERIT
:
1964 return &elf_mips_gnu_vtinherit_howto
;
1965 case BFD_RELOC_VTABLE_ENTRY
:
1966 return &elf_mips_gnu_vtentry_howto
;
1968 bfd_set_error (bfd_error_bad_value
);
1973 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1975 static reloc_howto_type
*
1976 mips_elf64_rtype_to_howto (r_type
, rela_p
)
1977 unsigned int r_type
;
1983 return &elf_mips16_jump_howto
;
1984 case R_MIPS16_GPREL
:
1985 return &elf_mips16_gprel_howto
;
1986 case R_MIPS_GNU_VTINHERIT
:
1987 return &elf_mips_gnu_vtinherit_howto
;
1988 case R_MIPS_GNU_VTENTRY
:
1989 return &elf_mips_gnu_vtentry_howto
;
1991 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
1993 return &mips_elf64_howto_table_rela
[r_type
];
1995 return &mips_elf64_howto_table_rel
[r_type
];
2000 /* Prevent relocation handling by bfd for MIPS ELF64. */
2003 mips_elf64_info_to_howto_rel (abfd
, cache_ptr
, dst
)
2004 bfd
*abfd ATTRIBUTE_UNUSED
;
2005 arelent
*cache_ptr ATTRIBUTE_UNUSED
;
2006 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
;
2012 mips_elf64_info_to_howto_rela (abfd
, cache_ptr
, dst
)
2013 bfd
*abfd ATTRIBUTE_UNUSED
;
2014 arelent
*cache_ptr ATTRIBUTE_UNUSED
;
2015 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
;
2020 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2021 to three relocs, we must tell the user to allocate more space. */
2024 mips_elf64_get_reloc_upper_bound (abfd
, sec
)
2025 bfd
*abfd ATTRIBUTE_UNUSED
;
2028 return (sec
->reloc_count
* 3 + 1) * sizeof (arelent
*);
2032 mips_elf64_get_dynamic_reloc_upper_bound (abfd
)
2035 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd
) * 3;
2038 /* We must also copy more relocations than the corresponding functions
2039 in elf.c would, so the two following functions are slightly
2040 modified from elf.c, that multiply the external relocation count by
2041 3 to obtain the internal relocation count. */
2044 mips_elf64_canonicalize_reloc (abfd
, section
, relptr
, symbols
)
2052 struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
2054 if (! bed
->s
->slurp_reloc_table (abfd
, section
, symbols
, FALSE
))
2057 tblptr
= section
->relocation
;
2058 for (i
= 0; i
< section
->reloc_count
* 3; i
++)
2059 *relptr
++ = tblptr
++;
2063 return section
->reloc_count
* 3;
2067 mips_elf64_canonicalize_dynamic_reloc (abfd
, storage
, syms
)
2072 bfd_boolean (*slurp_relocs
)
2073 PARAMS ((bfd
*, asection
*, asymbol
**, bfd_boolean
));
2077 if (elf_dynsymtab (abfd
) == 0)
2079 bfd_set_error (bfd_error_invalid_operation
);
2083 slurp_relocs
= get_elf_backend_data (abfd
)->s
->slurp_reloc_table
;
2085 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
2087 if (elf_section_data (s
)->this_hdr
.sh_link
== elf_dynsymtab (abfd
)
2088 && (elf_section_data (s
)->this_hdr
.sh_type
== SHT_REL
2089 || elf_section_data (s
)->this_hdr
.sh_type
== SHT_RELA
))
2094 if (! (*slurp_relocs
) (abfd
, s
, syms
, TRUE
))
2096 count
= s
->_raw_size
/ elf_section_data (s
)->this_hdr
.sh_entsize
* 3;
2098 for (i
= 0; i
< count
; i
++)
2109 /* Read the relocations from one reloc section. This is mostly copied
2110 from elfcode.h, except for the changes to expand one external
2111 relocation to 3 internal ones. We must unfortunately set
2112 reloc_count to the number of external relocations, because a lot of
2113 generic code seems to depend on this. */
2116 mips_elf64_slurp_one_reloc_table (abfd
, asect
, rel_hdr
, reloc_count
,
2117 relents
, symbols
, dynamic
)
2120 Elf_Internal_Shdr
*rel_hdr
;
2121 bfd_size_type reloc_count
;
2124 bfd_boolean dynamic
;
2126 PTR allocated
= NULL
;
2127 bfd_byte
*native_relocs
;
2131 reloc_howto_type
*howto_table
;
2133 allocated
= (PTR
) bfd_malloc (rel_hdr
->sh_size
);
2134 if (allocated
== NULL
)
2137 if (bfd_seek (abfd
, rel_hdr
->sh_offset
, SEEK_SET
) != 0
2138 || (bfd_bread (allocated
, rel_hdr
->sh_size
, abfd
)
2139 != rel_hdr
->sh_size
))
2142 native_relocs
= (bfd_byte
*) allocated
;
2144 entsize
= rel_hdr
->sh_entsize
;
2145 BFD_ASSERT (entsize
== sizeof (Elf64_Mips_External_Rel
)
2146 || entsize
== sizeof (Elf64_Mips_External_Rela
));
2148 if (entsize
== sizeof (Elf64_Mips_External_Rel
))
2149 howto_table
= mips_elf64_howto_table_rel
;
2151 howto_table
= mips_elf64_howto_table_rela
;
2153 for (i
= 0, relent
= relents
;
2155 i
++, native_relocs
+= entsize
)
2157 Elf64_Mips_Internal_Rela rela
;
2158 bfd_boolean used_sym
, used_ssym
;
2161 if (entsize
== sizeof (Elf64_Mips_External_Rela
))
2162 mips_elf64_swap_reloca_in (abfd
,
2163 (Elf64_Mips_External_Rela
*) native_relocs
,
2166 mips_elf64_swap_reloc_in (abfd
,
2167 (Elf64_Mips_External_Rel
*) native_relocs
,
2170 /* Each entry represents exactly three actual relocations. */
2174 for (ir
= 0; ir
< 3; ir
++)
2176 enum elf_mips_reloc_type type
;
2183 type
= (enum elf_mips_reloc_type
) rela
.r_type
;
2186 type
= (enum elf_mips_reloc_type
) rela
.r_type2
;
2189 type
= (enum elf_mips_reloc_type
) rela
.r_type3
;
2193 /* Some types require symbols, whereas some do not. */
2197 case R_MIPS_LITERAL
:
2198 case R_MIPS_INSERT_A
:
2199 case R_MIPS_INSERT_B
:
2201 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2207 if (rela
.r_sym
== 0)
2208 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2213 ps
= symbols
+ rela
.r_sym
- 1;
2215 if ((s
->flags
& BSF_SECTION_SYM
) == 0)
2216 relent
->sym_ptr_ptr
= ps
;
2218 relent
->sym_ptr_ptr
= s
->section
->symbol_ptr_ptr
;
2223 else if (! used_ssym
)
2225 switch (rela
.r_ssym
)
2228 relent
->sym_ptr_ptr
=
2229 bfd_abs_section_ptr
->symbol_ptr_ptr
;
2235 /* FIXME: I think these need to be handled using
2236 special howto structures. */
2248 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2253 /* The address of an ELF reloc is section relative for an
2254 object file, and absolute for an executable file or
2255 shared library. The address of a BFD reloc is always
2256 section relative. */
2257 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0 || dynamic
)
2258 relent
->address
= rela
.r_offset
;
2260 relent
->address
= rela
.r_offset
- asect
->vma
;
2262 relent
->addend
= rela
.r_addend
;
2264 relent
->howto
= &howto_table
[(int) type
];
2270 asect
->reloc_count
+= (relent
- relents
) / 3;
2272 if (allocated
!= NULL
)
2278 if (allocated
!= NULL
)
2283 /* Read the relocations. On Irix 6, there can be two reloc sections
2284 associated with a single data section. This is copied from
2285 elfcode.h as well, with changes as small as accounting for 3
2286 internal relocs per external reloc and resetting reloc_count to
2287 zero before processing the relocs of a section. */
2290 mips_elf64_slurp_reloc_table (abfd
, asect
, symbols
, dynamic
)
2294 bfd_boolean dynamic
;
2296 struct bfd_elf_section_data
* const d
= elf_section_data (asect
);
2297 Elf_Internal_Shdr
*rel_hdr
;
2298 Elf_Internal_Shdr
*rel_hdr2
;
2299 bfd_size_type reloc_count
;
2300 bfd_size_type reloc_count2
;
2304 if (asect
->relocation
!= NULL
)
2309 if ((asect
->flags
& SEC_RELOC
) == 0
2310 || asect
->reloc_count
== 0)
2313 rel_hdr
= &d
->rel_hdr
;
2314 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2315 rel_hdr2
= d
->rel_hdr2
;
2316 reloc_count2
= (rel_hdr2
? NUM_SHDR_ENTRIES (rel_hdr2
) : 0);
2318 BFD_ASSERT (asect
->reloc_count
== reloc_count
+ reloc_count2
);
2319 BFD_ASSERT (asect
->rel_filepos
== rel_hdr
->sh_offset
2320 || (rel_hdr2
&& asect
->rel_filepos
== rel_hdr2
->sh_offset
));
2325 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2326 case because relocations against this section may use the
2327 dynamic symbol table, and in that case bfd_section_from_shdr
2328 in elf.c does not update the RELOC_COUNT. */
2329 if (asect
->_raw_size
== 0)
2332 rel_hdr
= &d
->this_hdr
;
2333 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2338 /* Allocate space for 3 arelent structures for each Rel structure. */
2339 amt
= (reloc_count
+ reloc_count2
) * 3 * sizeof (arelent
);
2340 relents
= (arelent
*) bfd_alloc (abfd
, amt
);
2341 if (relents
== NULL
)
2344 /* The slurp_one_reloc_table routine increments reloc_count. */
2345 asect
->reloc_count
= 0;
2347 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2348 rel_hdr
, reloc_count
,
2352 if (d
->rel_hdr2
!= NULL
)
2354 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2355 rel_hdr2
, reloc_count2
,
2356 relents
+ reloc_count
* 3,
2361 asect
->relocation
= relents
;
2365 /* Write out the relocations. */
2368 mips_elf64_write_relocs (abfd
, sec
, data
)
2373 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2375 Elf_Internal_Shdr
*rel_hdr
;
2378 /* If we have already failed, don't do anything. */
2382 if ((sec
->flags
& SEC_RELOC
) == 0)
2385 /* The linker backend writes the relocs out itself, and sets the
2386 reloc_count field to zero to inhibit writing them here. Also,
2387 sometimes the SEC_RELOC flag gets set even when there aren't any
2389 if (sec
->reloc_count
== 0)
2392 /* We can combine up to three relocs that refer to the same address
2393 if the latter relocs have no associated symbol. */
2395 for (idx
= 0; idx
< sec
->reloc_count
; idx
++)
2402 addr
= sec
->orelocation
[idx
]->address
;
2403 for (i
= 0; i
< 2; i
++)
2407 if (idx
+ 1 >= sec
->reloc_count
)
2409 r
= sec
->orelocation
[idx
+ 1];
2410 if (r
->address
!= addr
2411 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2412 || (*r
->sym_ptr_ptr
)->value
!= 0)
2415 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2421 rel_hdr
= &elf_section_data (sec
)->rel_hdr
;
2423 /* Do the actual relocation. */
2425 if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rel
))
2426 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, &count
, data
);
2427 else if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rela
))
2428 mips_elf64_write_rela (abfd
, sec
, rel_hdr
, &count
, data
);
2434 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, count
, data
)
2437 Elf_Internal_Shdr
*rel_hdr
;
2441 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2442 Elf64_Mips_External_Rel
*ext_rel
;
2444 asymbol
*last_sym
= 0;
2445 int last_sym_idx
= 0;
2447 rel_hdr
->sh_size
= (bfd_vma
)(rel_hdr
->sh_entsize
* *count
);
2448 rel_hdr
->contents
= (PTR
) bfd_alloc (abfd
, rel_hdr
->sh_size
);
2449 if (rel_hdr
->contents
== NULL
)
2455 ext_rel
= (Elf64_Mips_External_Rel
*) rel_hdr
->contents
;
2456 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rel
++)
2459 Elf64_Mips_Internal_Rela int_rel
;
2464 ptr
= sec
->orelocation
[idx
];
2466 /* The address of an ELF reloc is section relative for an object
2467 file, and absolute for an executable file or shared library.
2468 The address of a BFD reloc is always section relative. */
2469 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2470 int_rel
.r_offset
= ptr
->address
;
2472 int_rel
.r_offset
= ptr
->address
+ sec
->vma
;
2474 sym
= *ptr
->sym_ptr_ptr
;
2475 if (sym
== last_sym
)
2480 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2490 int_rel
.r_ssym
= RSS_UNDEF
;
2492 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2493 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2499 int_rel
.r_type
= ptr
->howto
->type
;
2500 int_rel
.r_type2
= (int) R_MIPS_NONE
;
2501 int_rel
.r_type3
= (int) R_MIPS_NONE
;
2503 for (i
= 0; i
< 2; i
++)
2507 if (idx
+ 1 >= sec
->reloc_count
)
2509 r
= sec
->orelocation
[idx
+ 1];
2510 if (r
->address
!= ptr
->address
2511 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2512 || (*r
->sym_ptr_ptr
)->value
!= 0)
2515 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2518 int_rel
.r_type2
= r
->howto
->type
;
2520 int_rel
.r_type3
= r
->howto
->type
;
2525 mips_elf64_swap_reloc_out (abfd
, &int_rel
, ext_rel
);
2528 BFD_ASSERT (ext_rel
- (Elf64_Mips_External_Rel
*) rel_hdr
->contents
2533 mips_elf64_write_rela (abfd
, sec
, rela_hdr
, count
, data
)
2536 Elf_Internal_Shdr
*rela_hdr
;
2540 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2541 Elf64_Mips_External_Rela
*ext_rela
;
2543 asymbol
*last_sym
= 0;
2544 int last_sym_idx
= 0;
2546 rela_hdr
->sh_size
= (bfd_vma
)(rela_hdr
->sh_entsize
* *count
);
2547 rela_hdr
->contents
= (PTR
) bfd_alloc (abfd
, rela_hdr
->sh_size
);
2548 if (rela_hdr
->contents
== NULL
)
2554 ext_rela
= (Elf64_Mips_External_Rela
*) rela_hdr
->contents
;
2555 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rela
++)
2558 Elf64_Mips_Internal_Rela int_rela
;
2563 ptr
= sec
->orelocation
[idx
];
2565 /* The address of an ELF reloc is section relative for an object
2566 file, and absolute for an executable file or shared library.
2567 The address of a BFD reloc is always section relative. */
2568 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2569 int_rela
.r_offset
= ptr
->address
;
2571 int_rela
.r_offset
= ptr
->address
+ sec
->vma
;
2573 sym
= *ptr
->sym_ptr_ptr
;
2574 if (sym
== last_sym
)
2579 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2589 int_rela
.r_addend
= ptr
->addend
;
2590 int_rela
.r_ssym
= RSS_UNDEF
;
2592 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2593 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2599 int_rela
.r_type
= ptr
->howto
->type
;
2600 int_rela
.r_type2
= (int) R_MIPS_NONE
;
2601 int_rela
.r_type3
= (int) R_MIPS_NONE
;
2603 for (i
= 0; i
< 2; i
++)
2607 if (idx
+ 1 >= sec
->reloc_count
)
2609 r
= sec
->orelocation
[idx
+ 1];
2610 if (r
->address
!= ptr
->address
2611 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2612 || (*r
->sym_ptr_ptr
)->value
!= 0)
2615 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2618 int_rela
.r_type2
= r
->howto
->type
;
2620 int_rela
.r_type3
= r
->howto
->type
;
2625 mips_elf64_swap_reloca_out (abfd
, &int_rela
, ext_rela
);
2628 BFD_ASSERT (ext_rela
- (Elf64_Mips_External_Rela
*) rela_hdr
->contents
2632 /* Set the right machine number for a MIPS ELF file. */
2635 mips_elf64_object_p (abfd
)
2640 /* Irix 6 is broken. Object file symbol tables are not always
2641 sorted correctly such that local symbols precede global symbols,
2642 and the sh_info field in the symbol table is not always right. */
2643 if (elf64_mips_irix_compat (abfd
) != ict_none
)
2644 elf_bad_symtab (abfd
) = TRUE
;
2646 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
2647 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
2651 /* Depending on the target vector we generate some version of Irix
2652 executables or "normal" MIPS ELF ABI executables. */
2653 static irix_compat_t
2654 elf64_mips_irix_compat (abfd
)
2657 if ((abfd
->xvec
== &bfd_elf64_bigmips_vec
)
2658 || (abfd
->xvec
== &bfd_elf64_littlemips_vec
))
2664 /* Support for core dump NOTE sections. */
2666 elf64_mips_grok_prstatus (abfd
, note
)
2668 Elf_Internal_Note
*note
;
2671 unsigned int raw_size
;
2673 switch (note
->descsz
)
2678 case 480: /* Linux/MIPS - N64 kernel */
2680 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
2683 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 32);
2692 /* Make a ".reg/999" section. */
2693 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
2694 raw_size
, note
->descpos
+ offset
);
2698 elf64_mips_grok_psinfo (abfd
, note
)
2700 Elf_Internal_Note
*note
;
2702 switch (note
->descsz
)
2707 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2708 elf_tdata (abfd
)->core_program
2709 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
2710 elf_tdata (abfd
)->core_command
2711 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
2714 /* Note that for some reason, a spurious space is tacked
2715 onto the end of the args in some (at least one anyway)
2716 implementations, so strip it off if it exists. */
2719 char *command
= elf_tdata (abfd
)->core_command
;
2720 int n
= strlen (command
);
2722 if (0 < n
&& command
[n
- 1] == ' ')
2723 command
[n
- 1] = '\0';
2729 /* ECOFF swapping routines. These are used when dealing with the
2730 .mdebug section, which is in the ECOFF debugging format. */
2731 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap
=
2733 /* Symbol table magic number. */
2735 /* Alignment of debugging information. E.g., 4. */
2737 /* Sizes of external symbolic information. */
2738 sizeof (struct hdr_ext
),
2739 sizeof (struct dnr_ext
),
2740 sizeof (struct pdr_ext
),
2741 sizeof (struct sym_ext
),
2742 sizeof (struct opt_ext
),
2743 sizeof (struct fdr_ext
),
2744 sizeof (struct rfd_ext
),
2745 sizeof (struct ext_ext
),
2746 /* Functions to swap in external symbolic data. */
2755 _bfd_ecoff_swap_tir_in
,
2756 _bfd_ecoff_swap_rndx_in
,
2757 /* Functions to swap out external symbolic data. */
2766 _bfd_ecoff_swap_tir_out
,
2767 _bfd_ecoff_swap_rndx_out
,
2768 /* Function to read in symbolic data. */
2769 _bfd_mips_elf_read_ecoff_info
2772 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2773 standard ELF. This structure is used to redirect the relocation
2774 handling routines. */
2776 const struct elf_size_info mips_elf64_size_info
=
2778 sizeof (Elf64_External_Ehdr
),
2779 sizeof (Elf64_External_Phdr
),
2780 sizeof (Elf64_External_Shdr
),
2781 sizeof (Elf64_Mips_External_Rel
),
2782 sizeof (Elf64_Mips_External_Rela
),
2783 sizeof (Elf64_External_Sym
),
2784 sizeof (Elf64_External_Dyn
),
2785 sizeof (Elf_External_Note
),
2786 4, /* hash-table entry size */
2787 3, /* internal relocations per external relocations */
2792 bfd_elf64_write_out_phdrs
,
2793 bfd_elf64_write_shdrs_and_ehdr
,
2794 mips_elf64_write_relocs
,
2795 bfd_elf64_swap_symbol_in
,
2796 bfd_elf64_swap_symbol_out
,
2797 mips_elf64_slurp_reloc_table
,
2798 bfd_elf64_slurp_symbol_table
,
2799 bfd_elf64_swap_dyn_in
,
2800 bfd_elf64_swap_dyn_out
,
2801 mips_elf64_be_swap_reloc_in
,
2802 mips_elf64_be_swap_reloc_out
,
2803 mips_elf64_be_swap_reloca_in
,
2804 mips_elf64_be_swap_reloca_out
2807 #define ELF_ARCH bfd_arch_mips
2808 #define ELF_MACHINE_CODE EM_MIPS
2810 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2811 a value of 0x1000, and we are compatible.
2812 FIXME: How does this affect NewABI? */
2813 #define ELF_MAXPAGESIZE 0x1000
2815 #define elf_backend_collect TRUE
2816 #define elf_backend_type_change_ok TRUE
2817 #define elf_backend_can_gc_sections TRUE
2818 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2819 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2820 #define elf_backend_object_p mips_elf64_object_p
2821 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2822 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2823 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2824 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2825 #define elf_backend_section_from_bfd_section \
2826 _bfd_mips_elf_section_from_bfd_section
2827 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2828 #define elf_backend_link_output_symbol_hook \
2829 _bfd_mips_elf_link_output_symbol_hook
2830 #define elf_backend_create_dynamic_sections \
2831 _bfd_mips_elf_create_dynamic_sections
2832 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2833 #define elf_backend_adjust_dynamic_symbol \
2834 _bfd_mips_elf_adjust_dynamic_symbol
2835 #define elf_backend_always_size_sections \
2836 _bfd_mips_elf_always_size_sections
2837 #define elf_backend_size_dynamic_sections \
2838 _bfd_mips_elf_size_dynamic_sections
2839 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2840 #define elf_backend_finish_dynamic_symbol \
2841 _bfd_mips_elf_finish_dynamic_symbol
2842 #define elf_backend_finish_dynamic_sections \
2843 _bfd_mips_elf_finish_dynamic_sections
2844 #define elf_backend_final_write_processing \
2845 _bfd_mips_elf_final_write_processing
2846 #define elf_backend_additional_program_headers \
2847 _bfd_mips_elf_additional_program_headers
2848 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2849 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2850 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2851 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2852 #define elf_backend_ignore_discarded_relocs \
2853 _bfd_mips_elf_ignore_discarded_relocs
2854 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2855 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2856 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2857 #define elf_backend_size_info mips_elf64_size_info
2859 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
2860 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
2862 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2863 #define elf_backend_plt_header_size 0
2865 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2866 work better/work only in RELA, so we default to this. */
2867 #define elf_backend_may_use_rel_p 1
2868 #define elf_backend_may_use_rela_p 1
2869 #define elf_backend_default_use_rela_p 1
2871 #define elf_backend_write_section _bfd_mips_elf_write_section
2873 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2874 MIPS-specific function only applies to IRIX5, which had no 64-bit
2876 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2877 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
2878 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2879 #define bfd_elf64_bfd_get_relocated_section_contents \
2880 _bfd_elf_mips_get_relocated_section_contents
2881 #define bfd_elf64_bfd_link_hash_table_create \
2882 _bfd_mips_elf_link_hash_table_create
2883 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2884 #define bfd_elf64_bfd_merge_private_bfd_data \
2885 _bfd_mips_elf_merge_private_bfd_data
2886 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2887 #define bfd_elf64_bfd_print_private_bfd_data \
2888 _bfd_mips_elf_print_private_bfd_data
2890 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2891 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
2892 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
2893 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
2895 /* MIPS ELF64 archive functions. */
2896 #define bfd_elf64_archive_functions
2897 extern bfd_boolean bfd_elf64_archive_slurp_armap
2899 extern bfd_boolean bfd_elf64_archive_write_armap
2900 PARAMS ((bfd
*, unsigned int, struct orl
*, unsigned int, int));
2901 #define bfd_elf64_archive_slurp_extended_name_table \
2902 _bfd_archive_coff_slurp_extended_name_table
2903 #define bfd_elf64_archive_construct_extended_name_table \
2904 _bfd_archive_coff_construct_extended_name_table
2905 #define bfd_elf64_archive_truncate_arname \
2906 _bfd_archive_coff_truncate_arname
2907 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2908 #define bfd_elf64_archive_openr_next_archived_file \
2909 _bfd_archive_coff_openr_next_archived_file
2910 #define bfd_elf64_archive_get_elt_at_index \
2911 _bfd_archive_coff_get_elt_at_index
2912 #define bfd_elf64_archive_generic_stat_arch_elt \
2913 _bfd_archive_coff_generic_stat_arch_elt
2914 #define bfd_elf64_archive_update_armap_timestamp \
2915 _bfd_archive_coff_update_armap_timestamp
2917 /* The SGI style (n)64 NewABI. */
2918 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2919 #define TARGET_LITTLE_NAME "elf64-littlemips"
2920 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2921 #define TARGET_BIG_NAME "elf64-bigmips"
2923 #include "elf64-target.h"
2925 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2927 /* The SYSV-style 'traditional' (n)64 NewABI. */
2928 #undef TARGET_LITTLE_SYM
2929 #undef TARGET_LITTLE_NAME
2930 #undef TARGET_BIG_SYM
2931 #undef TARGET_BIG_NAME
2933 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2934 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2935 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2936 #define TARGET_BIG_NAME "elf64-tradbigmips"
2938 /* Include the target file again for this target. */
2939 #include "elf64-target.h"