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. */
310 HOWTO (R_MIPS_PC16
, /* type */
312 2, /* size (0 = byte, 1 = short, 2 = long) */
314 TRUE
, /* pc_relative */
316 complain_overflow_signed
, /* complain_on_overflow */
317 bfd_elf_generic_reloc
, /* special_function */
318 "R_MIPS_PC16", /* name */
319 TRUE
, /* partial_inplace */
320 0x0000ffff, /* src_mask */
321 0x0000ffff, /* dst_mask */
322 TRUE
), /* pcrel_offset */
324 /* 16 bit call through global offset table. */
325 HOWTO (R_MIPS_CALL16
, /* type */
327 2, /* size (0 = byte, 1 = short, 2 = long) */
329 FALSE
, /* pc_relative */
331 complain_overflow_signed
, /* complain_on_overflow */
332 bfd_elf_generic_reloc
, /* special_function */
333 "R_MIPS_CALL16", /* name */
334 TRUE
, /* partial_inplace */
335 0x0000ffff, /* src_mask */
336 0x0000ffff, /* dst_mask */
337 FALSE
), /* pcrel_offset */
339 /* 32 bit GP relative reference. */
340 HOWTO (R_MIPS_GPREL32
, /* type */
342 2, /* size (0 = byte, 1 = short, 2 = long) */
344 FALSE
, /* pc_relative */
346 complain_overflow_dont
, /* complain_on_overflow */
347 mips_elf64_gprel32_reloc
, /* special_function */
348 "R_MIPS_GPREL32", /* name */
349 TRUE
, /* partial_inplace */
350 0xffffffff, /* src_mask */
351 0xffffffff, /* dst_mask */
352 FALSE
), /* pcrel_offset */
358 /* A 5 bit shift field. */
359 HOWTO (R_MIPS_SHIFT5
, /* type */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
363 FALSE
, /* pc_relative */
365 complain_overflow_bitfield
, /* complain_on_overflow */
366 bfd_elf_generic_reloc
, /* special_function */
367 "R_MIPS_SHIFT5", /* name */
368 TRUE
, /* partial_inplace */
369 0x000007c0, /* src_mask */
370 0x000007c0, /* dst_mask */
371 FALSE
), /* pcrel_offset */
373 /* A 6 bit shift field. */
374 HOWTO (R_MIPS_SHIFT6
, /* type */
376 2, /* size (0 = byte, 1 = short, 2 = long) */
378 FALSE
, /* pc_relative */
380 complain_overflow_bitfield
, /* complain_on_overflow */
381 mips_elf64_shift6_reloc
, /* special_function */
382 "R_MIPS_SHIFT6", /* name */
383 TRUE
, /* partial_inplace */
384 0x000007c4, /* src_mask */
385 0x000007c4, /* dst_mask */
386 FALSE
), /* pcrel_offset */
388 /* 64 bit relocation. */
389 HOWTO (R_MIPS_64
, /* type */
391 4, /* size (0 = byte, 1 = short, 2 = long) */
393 FALSE
, /* pc_relative */
395 complain_overflow_dont
, /* complain_on_overflow */
396 bfd_elf_generic_reloc
, /* special_function */
397 "R_MIPS_64", /* name */
398 TRUE
, /* partial_inplace */
399 MINUS_ONE
, /* src_mask */
400 MINUS_ONE
, /* dst_mask */
401 FALSE
), /* pcrel_offset */
403 /* Displacement in the global offset table. */
404 HOWTO (R_MIPS_GOT_DISP
, /* type */
406 2, /* size (0 = byte, 1 = short, 2 = long) */
408 FALSE
, /* pc_relative */
410 complain_overflow_signed
, /* complain_on_overflow */
411 bfd_elf_generic_reloc
, /* special_function */
412 "R_MIPS_GOT_DISP", /* name */
413 TRUE
, /* partial_inplace */
414 0x0000ffff, /* src_mask */
415 0x0000ffff, /* dst_mask */
416 FALSE
), /* pcrel_offset */
418 /* Displacement to page pointer in the global offset table. */
419 HOWTO (R_MIPS_GOT_PAGE
, /* type */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
423 FALSE
, /* pc_relative */
425 complain_overflow_signed
, /* complain_on_overflow */
426 bfd_elf_generic_reloc
, /* special_function */
427 "R_MIPS_GOT_PAGE", /* name */
428 TRUE
, /* partial_inplace */
429 0x0000ffff, /* src_mask */
430 0x0000ffff, /* dst_mask */
431 FALSE
), /* pcrel_offset */
433 /* Offset from page pointer in the global offset table. */
434 HOWTO (R_MIPS_GOT_OFST
, /* type */
436 2, /* size (0 = byte, 1 = short, 2 = long) */
438 FALSE
, /* pc_relative */
440 complain_overflow_signed
, /* complain_on_overflow */
441 bfd_elf_generic_reloc
, /* special_function */
442 "R_MIPS_GOT_OFST", /* name */
443 TRUE
, /* partial_inplace */
444 0x0000ffff, /* src_mask */
445 0x0000ffff, /* dst_mask */
446 FALSE
), /* pcrel_offset */
448 /* High 16 bits of displacement in global offset table. */
449 HOWTO (R_MIPS_GOT_HI16
, /* type */
451 2, /* size (0 = byte, 1 = short, 2 = long) */
453 FALSE
, /* pc_relative */
455 complain_overflow_dont
, /* complain_on_overflow */
456 bfd_elf_generic_reloc
, /* special_function */
457 "R_MIPS_GOT_HI16", /* name */
458 TRUE
, /* partial_inplace */
459 0x0000ffff, /* src_mask */
460 0x0000ffff, /* dst_mask */
461 FALSE
), /* pcrel_offset */
463 /* Low 16 bits of displacement in global offset table. */
464 HOWTO (R_MIPS_GOT_LO16
, /* type */
466 2, /* size (0 = byte, 1 = short, 2 = long) */
468 FALSE
, /* pc_relative */
470 complain_overflow_dont
, /* complain_on_overflow */
471 bfd_elf_generic_reloc
, /* special_function */
472 "R_MIPS_GOT_LO16", /* name */
473 TRUE
, /* partial_inplace */
474 0x0000ffff, /* src_mask */
475 0x0000ffff, /* dst_mask */
476 FALSE
), /* pcrel_offset */
478 /* 64 bit substraction. */
479 HOWTO (R_MIPS_SUB
, /* type */
481 4, /* size (0 = byte, 1 = short, 2 = long) */
483 FALSE
, /* pc_relative */
485 complain_overflow_dont
, /* complain_on_overflow */
486 bfd_elf_generic_reloc
, /* special_function */
487 "R_MIPS_SUB", /* name */
488 TRUE
, /* partial_inplace */
489 MINUS_ONE
, /* src_mask */
490 MINUS_ONE
, /* dst_mask */
491 FALSE
), /* pcrel_offset */
493 /* Insert the addend as an instruction. */
494 /* FIXME: Not handled correctly. */
495 HOWTO (R_MIPS_INSERT_A
, /* type */
497 2, /* size (0 = byte, 1 = short, 2 = long) */
499 FALSE
, /* pc_relative */
501 complain_overflow_dont
, /* complain_on_overflow */
502 bfd_elf_generic_reloc
, /* special_function */
503 "R_MIPS_INSERT_A", /* name */
504 TRUE
, /* partial_inplace */
505 0xffffffff, /* src_mask */
506 0xffffffff, /* dst_mask */
507 FALSE
), /* pcrel_offset */
509 /* Insert the addend as an instruction, and change all relocations
510 to refer to the old instruction at the address. */
511 /* FIXME: Not handled correctly. */
512 HOWTO (R_MIPS_INSERT_B
, /* type */
514 2, /* size (0 = byte, 1 = short, 2 = long) */
516 FALSE
, /* pc_relative */
518 complain_overflow_dont
, /* complain_on_overflow */
519 bfd_elf_generic_reloc
, /* special_function */
520 "R_MIPS_INSERT_B", /* name */
521 TRUE
, /* partial_inplace */
522 0xffffffff, /* src_mask */
523 0xffffffff, /* dst_mask */
524 FALSE
), /* pcrel_offset */
526 /* Delete a 32 bit instruction. */
527 /* FIXME: Not handled correctly. */
528 HOWTO (R_MIPS_DELETE
, /* type */
530 2, /* size (0 = byte, 1 = short, 2 = long) */
532 FALSE
, /* pc_relative */
534 complain_overflow_dont
, /* complain_on_overflow */
535 bfd_elf_generic_reloc
, /* special_function */
536 "R_MIPS_DELETE", /* name */
537 TRUE
, /* partial_inplace */
538 0xffffffff, /* src_mask */
539 0xffffffff, /* dst_mask */
540 FALSE
), /* pcrel_offset */
542 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
544 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
545 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
547 b) No other NewABI toolchain actually emits such relocations. */
548 EMPTY_HOWTO (R_MIPS_HIGHER
),
549 EMPTY_HOWTO (R_MIPS_HIGHEST
),
551 /* High 16 bits of displacement in global offset table. */
552 HOWTO (R_MIPS_CALL_HI16
, /* type */
554 2, /* size (0 = byte, 1 = short, 2 = long) */
556 FALSE
, /* pc_relative */
558 complain_overflow_dont
, /* complain_on_overflow */
559 bfd_elf_generic_reloc
, /* special_function */
560 "R_MIPS_CALL_HI16", /* name */
561 TRUE
, /* partial_inplace */
562 0x0000ffff, /* src_mask */
563 0x0000ffff, /* dst_mask */
564 FALSE
), /* pcrel_offset */
566 /* Low 16 bits of displacement in global offset table. */
567 HOWTO (R_MIPS_CALL_LO16
, /* type */
569 2, /* size (0 = byte, 1 = short, 2 = long) */
571 FALSE
, /* pc_relative */
573 complain_overflow_dont
, /* complain_on_overflow */
574 bfd_elf_generic_reloc
, /* special_function */
575 "R_MIPS_CALL_LO16", /* name */
576 TRUE
, /* partial_inplace */
577 0x0000ffff, /* src_mask */
578 0x0000ffff, /* dst_mask */
579 FALSE
), /* pcrel_offset */
581 /* Section displacement, used by an associated event location section. */
582 HOWTO (R_MIPS_SCN_DISP
, /* type */
584 2, /* size (0 = byte, 1 = short, 2 = long) */
586 FALSE
, /* pc_relative */
588 complain_overflow_dont
, /* complain_on_overflow */
589 bfd_elf_generic_reloc
, /* special_function */
590 "R_MIPS_SCN_DISP", /* name */
591 TRUE
, /* partial_inplace */
592 0xffffffff, /* src_mask */
593 0xffffffff, /* dst_mask */
594 FALSE
), /* pcrel_offset */
596 HOWTO (R_MIPS_REL16
, /* type */
598 1, /* size (0 = byte, 1 = short, 2 = long) */
600 FALSE
, /* pc_relative */
602 complain_overflow_signed
, /* complain_on_overflow */
603 bfd_elf_generic_reloc
, /* special_function */
604 "R_MIPS_REL16", /* name */
605 TRUE
, /* partial_inplace */
606 0xffff, /* src_mask */
607 0xffff, /* dst_mask */
608 FALSE
), /* pcrel_offset */
610 /* These two are obsolete. */
611 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
612 EMPTY_HOWTO (R_MIPS_PJUMP
),
614 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
615 It must be used for multigot GOT's (and only there). */
616 HOWTO (R_MIPS_RELGOT
, /* type */
618 2, /* size (0 = byte, 1 = short, 2 = long) */
620 FALSE
, /* pc_relative */
622 complain_overflow_dont
, /* complain_on_overflow */
623 bfd_elf_generic_reloc
, /* special_function */
624 "R_MIPS_RELGOT", /* name */
625 TRUE
, /* partial_inplace */
626 0xffffffff, /* src_mask */
627 0xffffffff, /* dst_mask */
628 FALSE
), /* pcrel_offset */
630 /* Protected jump conversion. This is an optimization hint. No
631 relocation is required for correctness. */
632 HOWTO (R_MIPS_JALR
, /* type */
634 2, /* size (0 = byte, 1 = short, 2 = long) */
636 FALSE
, /* pc_relative */
638 complain_overflow_dont
, /* complain_on_overflow */
639 bfd_elf_generic_reloc
, /* special_function */
640 "R_MIPS_JALR", /* name */
641 FALSE
, /* partial_inplace */
643 0x00000000, /* dst_mask */
644 FALSE
), /* pcrel_offset */
647 /* The relocation table used for SHT_RELA sections. */
649 static reloc_howto_type mips_elf64_howto_table_rela
[] =
652 HOWTO (R_MIPS_NONE
, /* type */
654 0, /* size (0 = byte, 1 = short, 2 = long) */
656 FALSE
, /* pc_relative */
658 complain_overflow_dont
, /* complain_on_overflow */
659 bfd_elf_generic_reloc
, /* special_function */
660 "R_MIPS_NONE", /* name */
661 FALSE
, /* partial_inplace */
664 FALSE
), /* pcrel_offset */
666 /* 16 bit relocation. */
667 HOWTO (R_MIPS_16
, /* type */
669 2, /* size (0 = byte, 1 = short, 2 = long) */
671 FALSE
, /* pc_relative */
673 complain_overflow_signed
, /* complain_on_overflow */
674 bfd_elf_generic_reloc
, /* special_function */
675 "R_MIPS_16", /* name */
676 FALSE
, /* partial_inplace */
678 0x0000ffff, /* dst_mask */
679 FALSE
), /* pcrel_offset */
681 /* 32 bit relocation. */
682 HOWTO (R_MIPS_32
, /* type */
684 2, /* size (0 = byte, 1 = short, 2 = long) */
686 FALSE
, /* pc_relative */
688 complain_overflow_dont
, /* complain_on_overflow */
689 bfd_elf_generic_reloc
, /* special_function */
690 "R_MIPS_32", /* name */
691 FALSE
, /* partial_inplace */
693 0xffffffff, /* dst_mask */
694 FALSE
), /* pcrel_offset */
696 /* 32 bit symbol relative relocation. */
697 HOWTO (R_MIPS_REL32
, /* type */
699 2, /* size (0 = byte, 1 = short, 2 = long) */
701 FALSE
, /* pc_relative */
703 complain_overflow_dont
, /* complain_on_overflow */
704 bfd_elf_generic_reloc
, /* special_function */
705 "R_MIPS_REL32", /* name */
706 FALSE
, /* partial_inplace */
708 0xffffffff, /* dst_mask */
709 FALSE
), /* pcrel_offset */
711 /* 26 bit jump address. */
712 HOWTO (R_MIPS_26
, /* type */
714 2, /* size (0 = byte, 1 = short, 2 = long) */
716 FALSE
, /* pc_relative */
718 complain_overflow_dont
, /* complain_on_overflow */
719 /* This needs complex overflow
720 detection, because the upper 36
721 bits must match the PC + 4. */
722 bfd_elf_generic_reloc
, /* special_function */
723 "R_MIPS_26", /* name */
724 FALSE
, /* partial_inplace */
726 0x03ffffff, /* dst_mask */
727 FALSE
), /* pcrel_offset */
729 /* High 16 bits of symbol value. */
730 HOWTO (R_MIPS_HI16
, /* type */
732 2, /* size (0 = byte, 1 = short, 2 = long) */
734 FALSE
, /* pc_relative */
736 complain_overflow_dont
, /* complain_on_overflow */
737 bfd_elf_generic_reloc
, /* special_function */
738 "R_MIPS_HI16", /* name */
739 FALSE
, /* partial_inplace */
741 0x0000ffff, /* dst_mask */
742 FALSE
), /* pcrel_offset */
744 /* Low 16 bits of symbol value. */
745 HOWTO (R_MIPS_LO16
, /* type */
747 2, /* size (0 = byte, 1 = short, 2 = long) */
749 FALSE
, /* pc_relative */
751 complain_overflow_dont
, /* complain_on_overflow */
752 bfd_elf_generic_reloc
, /* special_function */
753 "R_MIPS_LO16", /* name */
754 FALSE
, /* partial_inplace */
756 0x0000ffff, /* dst_mask */
757 FALSE
), /* pcrel_offset */
759 /* GP relative reference. */
760 HOWTO (R_MIPS_GPREL16
, /* type */
762 2, /* size (0 = byte, 1 = short, 2 = long) */
764 FALSE
, /* pc_relative */
766 complain_overflow_signed
, /* complain_on_overflow */
767 mips_elf64_gprel16_reloc
, /* special_function */
768 "R_MIPS_GPREL16", /* name */
769 FALSE
, /* partial_inplace */
771 0x0000ffff, /* dst_mask */
772 FALSE
), /* pcrel_offset */
774 /* Reference to literal section. */
775 HOWTO (R_MIPS_LITERAL
, /* type */
777 2, /* size (0 = byte, 1 = short, 2 = long) */
779 FALSE
, /* pc_relative */
781 complain_overflow_signed
, /* complain_on_overflow */
782 mips_elf64_literal_reloc
, /* special_function */
783 "R_MIPS_LITERAL", /* name */
784 FALSE
, /* partial_inplace */
786 0x0000ffff, /* dst_mask */
787 FALSE
), /* pcrel_offset */
789 /* Reference to global offset table. */
790 HOWTO (R_MIPS_GOT16
, /* type */
792 2, /* size (0 = byte, 1 = short, 2 = long) */
794 FALSE
, /* pc_relative */
796 complain_overflow_signed
, /* complain_on_overflow */
797 mips_elf64_got16_reloc
, /* special_function */
798 "R_MIPS_GOT16", /* name */
799 FALSE
, /* partial_inplace */
801 0x0000ffff, /* dst_mask */
802 FALSE
), /* pcrel_offset */
804 /* 16 bit PC relative reference. */
805 HOWTO (R_MIPS_PC16
, /* type */
807 2, /* size (0 = byte, 1 = short, 2 = long) */
809 TRUE
, /* pc_relative */
811 complain_overflow_signed
, /* complain_on_overflow */
812 bfd_elf_generic_reloc
, /* special_function */
813 "R_MIPS_PC16", /* name */
814 FALSE
, /* partial_inplace */
816 0x0000ffff, /* dst_mask */
817 TRUE
), /* pcrel_offset */
819 /* 16 bit call through global offset table. */
820 HOWTO (R_MIPS_CALL16
, /* type */
822 2, /* size (0 = byte, 1 = short, 2 = long) */
824 FALSE
, /* pc_relative */
826 complain_overflow_signed
, /* complain_on_overflow */
827 bfd_elf_generic_reloc
, /* special_function */
828 "R_MIPS_CALL16", /* name */
829 FALSE
, /* partial_inplace */
831 0x0000ffff, /* dst_mask */
832 FALSE
), /* pcrel_offset */
834 /* 32 bit GP relative reference. */
835 HOWTO (R_MIPS_GPREL32
, /* type */
837 2, /* size (0 = byte, 1 = short, 2 = long) */
839 FALSE
, /* pc_relative */
841 complain_overflow_dont
, /* complain_on_overflow */
842 mips_elf64_gprel32_reloc
, /* special_function */
843 "R_MIPS_GPREL32", /* name */
844 FALSE
, /* partial_inplace */
846 0xffffffff, /* dst_mask */
847 FALSE
), /* pcrel_offset */
853 /* A 5 bit shift field. */
854 HOWTO (R_MIPS_SHIFT5
, /* type */
856 2, /* size (0 = byte, 1 = short, 2 = long) */
858 FALSE
, /* pc_relative */
860 complain_overflow_bitfield
, /* complain_on_overflow */
861 bfd_elf_generic_reloc
, /* special_function */
862 "R_MIPS_SHIFT5", /* name */
863 FALSE
, /* partial_inplace */
865 0x000007c0, /* dst_mask */
866 FALSE
), /* pcrel_offset */
868 /* A 6 bit shift field. */
869 HOWTO (R_MIPS_SHIFT6
, /* type */
871 2, /* size (0 = byte, 1 = short, 2 = long) */
873 FALSE
, /* pc_relative */
875 complain_overflow_bitfield
, /* complain_on_overflow */
876 mips_elf64_shift6_reloc
, /* special_function */
877 "R_MIPS_SHIFT6", /* name */
878 FALSE
, /* partial_inplace */
880 0x000007c4, /* dst_mask */
881 FALSE
), /* pcrel_offset */
883 /* 64 bit relocation. */
884 HOWTO (R_MIPS_64
, /* type */
886 4, /* size (0 = byte, 1 = short, 2 = long) */
888 FALSE
, /* pc_relative */
890 complain_overflow_dont
, /* complain_on_overflow */
891 bfd_elf_generic_reloc
, /* special_function */
892 "R_MIPS_64", /* name */
893 FALSE
, /* partial_inplace */
895 MINUS_ONE
, /* dst_mask */
896 FALSE
), /* pcrel_offset */
898 /* Displacement in the global offset table. */
899 HOWTO (R_MIPS_GOT_DISP
, /* type */
901 2, /* size (0 = byte, 1 = short, 2 = long) */
903 FALSE
, /* pc_relative */
905 complain_overflow_signed
, /* complain_on_overflow */
906 bfd_elf_generic_reloc
, /* special_function */
907 "R_MIPS_GOT_DISP", /* name */
908 FALSE
, /* partial_inplace */
910 0x0000ffff, /* dst_mask */
911 FALSE
), /* pcrel_offset */
913 /* Displacement to page pointer in the global offset table. */
914 HOWTO (R_MIPS_GOT_PAGE
, /* type */
916 2, /* size (0 = byte, 1 = short, 2 = long) */
918 FALSE
, /* pc_relative */
920 complain_overflow_signed
, /* complain_on_overflow */
921 bfd_elf_generic_reloc
, /* special_function */
922 "R_MIPS_GOT_PAGE", /* name */
923 FALSE
, /* partial_inplace */
925 0x0000ffff, /* dst_mask */
926 FALSE
), /* pcrel_offset */
928 /* Offset from page pointer in the global offset table. */
929 HOWTO (R_MIPS_GOT_OFST
, /* type */
931 2, /* size (0 = byte, 1 = short, 2 = long) */
933 FALSE
, /* pc_relative */
935 complain_overflow_signed
, /* complain_on_overflow */
936 bfd_elf_generic_reloc
, /* special_function */
937 "R_MIPS_GOT_OFST", /* name */
938 FALSE
, /* partial_inplace */
940 0x0000ffff, /* dst_mask */
941 FALSE
), /* pcrel_offset */
943 /* High 16 bits of displacement in global offset table. */
944 HOWTO (R_MIPS_GOT_HI16
, /* type */
946 2, /* size (0 = byte, 1 = short, 2 = long) */
948 FALSE
, /* pc_relative */
950 complain_overflow_dont
, /* complain_on_overflow */
951 bfd_elf_generic_reloc
, /* special_function */
952 "R_MIPS_GOT_HI16", /* name */
953 FALSE
, /* partial_inplace */
955 0x0000ffff, /* dst_mask */
956 FALSE
), /* pcrel_offset */
958 /* Low 16 bits of displacement in global offset table. */
959 HOWTO (R_MIPS_GOT_LO16
, /* type */
961 2, /* size (0 = byte, 1 = short, 2 = long) */
963 FALSE
, /* pc_relative */
965 complain_overflow_dont
, /* complain_on_overflow */
966 bfd_elf_generic_reloc
, /* special_function */
967 "R_MIPS_GOT_LO16", /* name */
968 FALSE
, /* partial_inplace */
970 0x0000ffff, /* dst_mask */
971 FALSE
), /* pcrel_offset */
973 /* 64 bit substraction. */
974 HOWTO (R_MIPS_SUB
, /* type */
976 4, /* size (0 = byte, 1 = short, 2 = long) */
978 FALSE
, /* pc_relative */
980 complain_overflow_dont
, /* complain_on_overflow */
981 bfd_elf_generic_reloc
, /* special_function */
982 "R_MIPS_SUB", /* name */
983 FALSE
, /* partial_inplace */
985 MINUS_ONE
, /* dst_mask */
986 FALSE
), /* pcrel_offset */
988 /* Insert the addend as an instruction. */
989 /* FIXME: Not handled correctly. */
990 HOWTO (R_MIPS_INSERT_A
, /* type */
992 2, /* size (0 = byte, 1 = short, 2 = long) */
994 FALSE
, /* pc_relative */
996 complain_overflow_dont
, /* complain_on_overflow */
997 bfd_elf_generic_reloc
, /* special_function */
998 "R_MIPS_INSERT_A", /* name */
999 FALSE
, /* partial_inplace */
1001 0xffffffff, /* dst_mask */
1002 FALSE
), /* pcrel_offset */
1004 /* Insert the addend as an instruction, and change all relocations
1005 to refer to the old instruction at the address. */
1006 /* FIXME: Not handled correctly. */
1007 HOWTO (R_MIPS_INSERT_B
, /* type */
1009 2, /* size (0 = byte, 1 = short, 2 = long) */
1011 FALSE
, /* pc_relative */
1013 complain_overflow_dont
, /* complain_on_overflow */
1014 bfd_elf_generic_reloc
, /* special_function */
1015 "R_MIPS_INSERT_B", /* name */
1016 FALSE
, /* partial_inplace */
1018 0xffffffff, /* dst_mask */
1019 FALSE
), /* pcrel_offset */
1021 /* Delete a 32 bit instruction. */
1022 /* FIXME: Not handled correctly. */
1023 HOWTO (R_MIPS_DELETE
, /* type */
1025 2, /* size (0 = byte, 1 = short, 2 = long) */
1027 FALSE
, /* pc_relative */
1029 complain_overflow_dont
, /* complain_on_overflow */
1030 bfd_elf_generic_reloc
, /* special_function */
1031 "R_MIPS_DELETE", /* name */
1032 FALSE
, /* partial_inplace */
1034 0xffffffff, /* dst_mask */
1035 FALSE
), /* pcrel_offset */
1037 /* Get the higher value of a 64 bit addend. */
1038 HOWTO (R_MIPS_HIGHER
, /* type */
1040 2, /* size (0 = byte, 1 = short, 2 = long) */
1042 FALSE
, /* pc_relative */
1044 complain_overflow_dont
, /* complain_on_overflow */
1045 bfd_elf_generic_reloc
, /* special_function */
1046 "R_MIPS_HIGHER", /* name */
1047 FALSE
, /* partial_inplace */
1049 0x0000ffff, /* dst_mask */
1050 FALSE
), /* pcrel_offset */
1052 /* Get the highest value of a 64 bit addend. */
1053 HOWTO (R_MIPS_HIGHEST
, /* type */
1055 2, /* size (0 = byte, 1 = short, 2 = long) */
1057 FALSE
, /* pc_relative */
1059 complain_overflow_dont
, /* complain_on_overflow */
1060 bfd_elf_generic_reloc
, /* special_function */
1061 "R_MIPS_HIGHEST", /* name */
1062 FALSE
, /* partial_inplace */
1064 0x0000ffff, /* dst_mask */
1065 FALSE
), /* pcrel_offset */
1067 /* High 16 bits of displacement in global offset table. */
1068 HOWTO (R_MIPS_CALL_HI16
, /* type */
1070 2, /* size (0 = byte, 1 = short, 2 = long) */
1072 FALSE
, /* pc_relative */
1074 complain_overflow_dont
, /* complain_on_overflow */
1075 bfd_elf_generic_reloc
, /* special_function */
1076 "R_MIPS_CALL_HI16", /* name */
1077 FALSE
, /* partial_inplace */
1079 0x0000ffff, /* dst_mask */
1080 FALSE
), /* pcrel_offset */
1082 /* Low 16 bits of displacement in global offset table. */
1083 HOWTO (R_MIPS_CALL_LO16
, /* type */
1085 2, /* size (0 = byte, 1 = short, 2 = long) */
1087 FALSE
, /* pc_relative */
1089 complain_overflow_dont
, /* complain_on_overflow */
1090 bfd_elf_generic_reloc
, /* special_function */
1091 "R_MIPS_CALL_LO16", /* name */
1092 FALSE
, /* partial_inplace */
1094 0x0000ffff, /* dst_mask */
1095 FALSE
), /* pcrel_offset */
1097 /* Section displacement, used by an associated event location section. */
1098 HOWTO (R_MIPS_SCN_DISP
, /* type */
1100 2, /* size (0 = byte, 1 = short, 2 = long) */
1102 FALSE
, /* pc_relative */
1104 complain_overflow_dont
, /* complain_on_overflow */
1105 bfd_elf_generic_reloc
, /* special_function */
1106 "R_MIPS_SCN_DISP", /* name */
1107 FALSE
, /* partial_inplace */
1109 0xffffffff, /* dst_mask */
1110 FALSE
), /* pcrel_offset */
1112 HOWTO (R_MIPS_REL16
, /* type */
1114 1, /* size (0 = byte, 1 = short, 2 = long) */
1116 FALSE
, /* pc_relative */
1118 complain_overflow_signed
, /* complain_on_overflow */
1119 bfd_elf_generic_reloc
, /* special_function */
1120 "R_MIPS_REL16", /* name */
1121 FALSE
, /* partial_inplace */
1123 0xffff, /* dst_mask */
1124 FALSE
), /* pcrel_offset */
1126 /* These two are obsolete. */
1127 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
1128 EMPTY_HOWTO (R_MIPS_PJUMP
),
1130 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1131 It must be used for multigot GOT's (and only there). */
1132 HOWTO (R_MIPS_RELGOT
, /* type */
1134 2, /* size (0 = byte, 1 = short, 2 = long) */
1136 FALSE
, /* pc_relative */
1138 complain_overflow_dont
, /* complain_on_overflow */
1139 bfd_elf_generic_reloc
, /* special_function */
1140 "R_MIPS_RELGOT", /* name */
1141 FALSE
, /* partial_inplace */
1143 0xffffffff, /* dst_mask */
1144 FALSE
), /* pcrel_offset */
1146 /* Protected jump conversion. This is an optimization hint. No
1147 relocation is required for correctness. */
1148 HOWTO (R_MIPS_JALR
, /* type */
1150 2, /* size (0 = byte, 1 = short, 2 = long) */
1152 FALSE
, /* pc_relative */
1154 complain_overflow_dont
, /* complain_on_overflow */
1155 bfd_elf_generic_reloc
, /* special_function */
1156 "R_MIPS_JALR", /* name */
1157 FALSE
, /* partial_inplace */
1159 0x00000000, /* dst_mask */
1160 FALSE
), /* pcrel_offset */
1163 /* The reloc used for the mips16 jump instruction. */
1164 static reloc_howto_type elf_mips16_jump_howto
=
1165 HOWTO (R_MIPS16_26
, /* type */
1167 2, /* size (0 = byte, 1 = short, 2 = long) */
1169 FALSE
, /* pc_relative */
1171 complain_overflow_dont
, /* complain_on_overflow */
1172 /* This needs complex overflow
1173 detection, because the upper four
1174 bits must match the PC. */
1175 mips16_jump_reloc
, /* special_function */
1176 "R_MIPS16_26", /* name */
1177 TRUE
, /* partial_inplace */
1178 0x3ffffff, /* src_mask */
1179 0x3ffffff, /* dst_mask */
1180 FALSE
); /* pcrel_offset */
1182 /* The reloc used for the mips16 gprel instruction. */
1183 static reloc_howto_type elf_mips16_gprel_howto
=
1184 HOWTO (R_MIPS16_GPREL
, /* type */
1186 2, /* size (0 = byte, 1 = short, 2 = long) */
1188 FALSE
, /* pc_relative */
1190 complain_overflow_signed
, /* complain_on_overflow */
1191 mips16_gprel_reloc
, /* special_function */
1192 "R_MIPS16_GPREL", /* name */
1193 TRUE
, /* partial_inplace */
1194 0x07ff001f, /* src_mask */
1195 0x07ff001f, /* dst_mask */
1196 FALSE
); /* pcrel_offset */
1198 /* GNU extension to record C++ vtable hierarchy */
1199 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
1200 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
1202 2, /* size (0 = byte, 1 = short, 2 = long) */
1204 FALSE
, /* pc_relative */
1206 complain_overflow_dont
, /* complain_on_overflow */
1207 NULL
, /* special_function */
1208 "R_MIPS_GNU_VTINHERIT", /* name */
1209 FALSE
, /* partial_inplace */
1212 FALSE
); /* pcrel_offset */
1214 /* GNU extension to record C++ vtable member usage */
1215 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
1216 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
1218 2, /* size (0 = byte, 1 = short, 2 = long) */
1220 FALSE
, /* pc_relative */
1222 complain_overflow_dont
, /* complain_on_overflow */
1223 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
1224 "R_MIPS_GNU_VTENTRY", /* name */
1225 FALSE
, /* partial_inplace */
1228 FALSE
); /* pcrel_offset */
1230 /* 16 bit offset for pc-relative branches. */
1231 static reloc_howto_type elf_mips_gnu_rel16_s2
=
1232 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1234 2, /* size (0 = byte, 1 = short, 2 = long) */
1236 TRUE
, /* pc_relative */
1238 complain_overflow_signed
, /* complain_on_overflow */
1239 bfd_elf_generic_reloc
, /* special_function */
1240 "R_MIPS_GNU_REL16_S2", /* name */
1241 TRUE
, /* partial_inplace */
1242 0x0000ffff, /* src_mask */
1243 0x0000ffff, /* dst_mask */
1244 TRUE
); /* pcrel_offset */
1246 /* 16 bit offset for pc-relative branches. */
1247 static reloc_howto_type elf_mips_gnu_rela16_s2
=
1248 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1250 2, /* size (0 = byte, 1 = short, 2 = long) */
1252 TRUE
, /* pc_relative */
1254 complain_overflow_signed
, /* complain_on_overflow */
1255 bfd_elf_generic_reloc
, /* special_function */
1256 "R_MIPS_GNU_REL16_S2", /* name */
1257 FALSE
, /* partial_inplace */
1259 0x0000ffff, /* dst_mask */
1260 TRUE
); /* pcrel_offset */
1262 /* Swap in a MIPS 64-bit Rel reloc. */
1265 mips_elf64_swap_reloc_in (abfd
, src
, dst
)
1267 const Elf64_Mips_External_Rel
*src
;
1268 Elf64_Mips_Internal_Rela
*dst
;
1270 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1271 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1272 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1273 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1274 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1275 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1279 /* Swap in a MIPS 64-bit Rela reloc. */
1282 mips_elf64_swap_reloca_in (abfd
, src
, dst
)
1284 const Elf64_Mips_External_Rela
*src
;
1285 Elf64_Mips_Internal_Rela
*dst
;
1287 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1288 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1289 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1290 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1291 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1292 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1293 dst
->r_addend
= H_GET_S64 (abfd
, src
->r_addend
);
1296 /* Swap out a MIPS 64-bit Rel reloc. */
1299 mips_elf64_swap_reloc_out (abfd
, src
, dst
)
1301 const Elf64_Mips_Internal_Rela
*src
;
1302 Elf64_Mips_External_Rel
*dst
;
1304 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1305 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1306 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1307 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1308 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1309 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1312 /* Swap out a MIPS 64-bit Rela reloc. */
1315 mips_elf64_swap_reloca_out (abfd
, src
, dst
)
1317 const Elf64_Mips_Internal_Rela
*src
;
1318 Elf64_Mips_External_Rela
*dst
;
1320 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1321 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1322 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1323 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1324 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1325 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1326 H_PUT_S64 (abfd
, src
->r_addend
, dst
->r_addend
);
1329 /* Swap in a MIPS 64-bit Rel reloc. */
1332 mips_elf64_be_swap_reloc_in (abfd
, src
, dst
)
1334 const bfd_byte
*src
;
1335 Elf_Internal_Rela
*dst
;
1337 Elf64_Mips_Internal_Rela mirel
;
1339 mips_elf64_swap_reloc_in (abfd
,
1340 (const Elf64_Mips_External_Rel
*) src
,
1343 dst
[0].r_offset
= mirel
.r_offset
;
1344 dst
[0].r_info
= ELF64_R_INFO (mirel
.r_sym
, mirel
.r_type
);
1345 dst
[0].r_addend
= 0;
1346 dst
[1].r_offset
= mirel
.r_offset
;
1347 dst
[1].r_info
= ELF64_R_INFO (mirel
.r_ssym
, mirel
.r_type2
);
1348 dst
[1].r_addend
= 0;
1349 dst
[2].r_offset
= mirel
.r_offset
;
1350 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirel
.r_type3
);
1351 dst
[2].r_addend
= 0;
1354 /* Swap in a MIPS 64-bit Rela reloc. */
1357 mips_elf64_be_swap_reloca_in (abfd
, src
, dst
)
1359 const bfd_byte
*src
;
1360 Elf_Internal_Rela
*dst
;
1362 Elf64_Mips_Internal_Rela mirela
;
1364 mips_elf64_swap_reloca_in (abfd
,
1365 (const Elf64_Mips_External_Rela
*) src
,
1368 dst
[0].r_offset
= mirela
.r_offset
;
1369 dst
[0].r_info
= ELF64_R_INFO (mirela
.r_sym
, mirela
.r_type
);
1370 dst
[0].r_addend
= mirela
.r_addend
;
1371 dst
[1].r_offset
= mirela
.r_offset
;
1372 dst
[1].r_info
= ELF64_R_INFO (mirela
.r_ssym
, mirela
.r_type2
);
1373 dst
[1].r_addend
= 0;
1374 dst
[2].r_offset
= mirela
.r_offset
;
1375 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirela
.r_type3
);
1376 dst
[2].r_addend
= 0;
1379 /* Swap out a MIPS 64-bit Rel reloc. */
1382 mips_elf64_be_swap_reloc_out (abfd
, src
, dst
)
1384 const Elf_Internal_Rela
*src
;
1387 Elf64_Mips_Internal_Rela mirel
;
1389 mirel
.r_offset
= src
[0].r_offset
;
1390 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1392 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1395 mirel
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1396 mirel
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1397 mirel
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1398 mirel
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1399 mirel
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1401 mips_elf64_swap_reloc_out (abfd
, &mirel
,
1402 (Elf64_Mips_External_Rel
*) dst
);
1405 /* Swap out a MIPS 64-bit Rela reloc. */
1408 mips_elf64_be_swap_reloca_out (abfd
, src
, dst
)
1410 const Elf_Internal_Rela
*src
;
1413 Elf64_Mips_Internal_Rela mirela
;
1415 mirela
.r_offset
= src
[0].r_offset
;
1416 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1417 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1419 mirela
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1420 mirela
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1421 mirela
.r_addend
= src
[0].r_addend
;
1422 BFD_ASSERT(src
[1].r_addend
== 0);
1423 BFD_ASSERT(src
[2].r_addend
== 0);
1425 mirela
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1426 mirela
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1427 mirela
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1429 mips_elf64_swap_reloca_out (abfd
, &mirela
,
1430 (Elf64_Mips_External_Rela
*) dst
);
1433 /* Do a R_MIPS_HI16 relocation. */
1435 static bfd_reloc_status_type
1436 mips_elf64_hi16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1437 output_bfd
, error_message
)
1438 bfd
*abfd ATTRIBUTE_UNUSED
;
1439 arelent
*reloc_entry
;
1441 PTR data ATTRIBUTE_UNUSED
;
1442 asection
*input_section
;
1444 char **error_message ATTRIBUTE_UNUSED
;
1446 /* If we're relocating, and this is an external symbol, we don't
1447 want to change anything. */
1448 if (output_bfd
!= (bfd
*) NULL
1449 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1450 && (! reloc_entry
->howto
->partial_inplace
1451 || reloc_entry
->addend
== 0))
1453 reloc_entry
->address
+= input_section
->output_offset
;
1454 return bfd_reloc_ok
;
1457 if (((reloc_entry
->addend
& 0xffff) + 0x8000) & ~0xffff)
1458 reloc_entry
->addend
+= 0x8000;
1460 return bfd_reloc_continue
;
1463 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1464 table used for PIC code. If the symbol is an external symbol, the
1465 instruction is modified to contain the offset of the appropriate
1466 entry in the global offset table. If the symbol is a section
1467 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1468 addends are combined to form the real addend against the section
1469 symbol; the GOT16 is modified to contain the offset of an entry in
1470 the global offset table, and the LO16 is modified to offset it
1471 appropriately. Thus an offset larger than 16 bits requires a
1472 modified value in the global offset table.
1474 This implementation suffices for the assembler, but the linker does
1475 not yet know how to create global offset tables. */
1477 static bfd_reloc_status_type
1478 mips_elf64_got16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1479 output_bfd
, error_message
)
1481 arelent
*reloc_entry
;
1484 asection
*input_section
;
1486 char **error_message
;
1488 /* If we're relocating, and this is a local symbol, we can handle it
1489 just like an R_MIPS_HI16. */
1490 if (output_bfd
!= (bfd
*) NULL
1491 && (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1492 return mips_elf64_hi16_reloc (abfd
, reloc_entry
, symbol
, data
,
1493 input_section
, output_bfd
, error_message
);
1496 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1497 return bfd_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
1498 input_section
, output_bfd
, error_message
);
1501 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1502 dangerous relocation. */
1505 mips_elf64_assign_gp (output_bfd
, pgp
)
1513 /* If we've already figured out what GP will be, just return it. */
1514 *pgp
= _bfd_get_gp_value (output_bfd
);
1518 count
= bfd_get_symcount (output_bfd
);
1519 sym
= bfd_get_outsymbols (output_bfd
);
1521 /* The linker script will have created a symbol named `_gp' with the
1522 appropriate value. */
1523 if (sym
== (asymbol
**) NULL
)
1527 for (i
= 0; i
< count
; i
++, sym
++)
1529 register const char *name
;
1531 name
= bfd_asymbol_name (*sym
);
1532 if (*name
== '_' && strcmp (name
, "_gp") == 0)
1534 *pgp
= bfd_asymbol_value (*sym
);
1535 _bfd_set_gp_value (output_bfd
, *pgp
);
1543 /* Only get the error once. */
1545 _bfd_set_gp_value (output_bfd
, *pgp
);
1552 /* We have to figure out the gp value, so that we can adjust the
1553 symbol value correctly. We look up the symbol _gp in the output
1554 BFD. If we can't find it, we're stuck. We cache it in the ELF
1555 target data. We don't need to adjust the symbol value for an
1556 external symbol if we are producing relocateable output. */
1558 static bfd_reloc_status_type
1559 mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
, pgp
)
1562 bfd_boolean relocateable
;
1563 char **error_message
;
1566 if (bfd_is_und_section (symbol
->section
)
1570 return bfd_reloc_undefined
;
1573 *pgp
= _bfd_get_gp_value (output_bfd
);
1576 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
1580 /* Make up a value. */
1581 *pgp
= symbol
->section
->output_section
->vma
/*+ 0x4000*/;
1582 _bfd_set_gp_value (output_bfd
, *pgp
);
1584 else if (!mips_elf64_assign_gp (output_bfd
, pgp
))
1587 (char *) _("GP relative relocation when _gp not defined");
1588 return bfd_reloc_dangerous
;
1592 return bfd_reloc_ok
;
1595 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1596 become the offset from the gp register. */
1598 static bfd_reloc_status_type
1599 mips_elf64_gprel16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1600 output_bfd
, error_message
)
1602 arelent
*reloc_entry
;
1605 asection
*input_section
;
1607 char **error_message
;
1609 bfd_boolean relocateable
;
1610 bfd_reloc_status_type ret
;
1613 /* If we're relocating, and this is an external symbol with no
1614 addend, we don't want to change anything. We will only have an
1615 addend if this is a newly created reloc, not read from an ELF
1617 if (output_bfd
!= (bfd
*) NULL
1618 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1619 && (! reloc_entry
->howto
->partial_inplace
1620 || reloc_entry
->addend
== 0))
1622 reloc_entry
->address
+= input_section
->output_offset
;
1623 return bfd_reloc_ok
;
1626 if (output_bfd
!= (bfd
*) NULL
)
1627 relocateable
= TRUE
;
1630 relocateable
= FALSE
;
1631 output_bfd
= symbol
->section
->output_section
->owner
;
1634 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1636 if (ret
!= bfd_reloc_ok
)
1639 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1640 input_section
, relocateable
,
1644 /* Do a R_MIPS_LITERAL relocation. */
1646 static bfd_reloc_status_type
1647 mips_elf64_literal_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1648 output_bfd
, error_message
)
1650 arelent
*reloc_entry
;
1653 asection
*input_section
;
1655 char **error_message
;
1657 bfd_boolean relocateable
;
1658 bfd_reloc_status_type ret
;
1661 /* If we're relocating, and this is an external symbol, we don't
1662 want to change anything. */
1663 if (output_bfd
!= (bfd
*) NULL
1664 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1665 && (! reloc_entry
->howto
->partial_inplace
1666 || reloc_entry
->addend
== 0))
1668 reloc_entry
->address
+= input_section
->output_offset
;
1669 return bfd_reloc_ok
;
1672 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1673 if (output_bfd
!= (bfd
*) NULL
)
1674 relocateable
= TRUE
;
1677 relocateable
= FALSE
;
1678 output_bfd
= symbol
->section
->output_section
->owner
;
1681 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1683 if (ret
!= bfd_reloc_ok
)
1686 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1687 input_section
, relocateable
,
1691 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1692 become the offset from the gp register. */
1694 static bfd_reloc_status_type
1695 mips_elf64_gprel32_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1696 output_bfd
, error_message
)
1698 arelent
*reloc_entry
;
1701 asection
*input_section
;
1703 char **error_message
;
1705 bfd_boolean relocateable
;
1706 bfd_reloc_status_type ret
;
1711 /* If we're relocating, and this is an external symbol with no
1712 addend, we don't want to change anything. We will only have an
1713 addend if this is a newly created reloc, not read from an ELF
1715 if (output_bfd
!= (bfd
*) NULL
1716 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1717 && reloc_entry
->addend
== 0)
1719 *error_message
= (char *)
1720 _("32bits gp relative relocation occurs for an external symbol");
1721 return bfd_reloc_outofrange
;
1724 if (output_bfd
!= (bfd
*) NULL
)
1726 relocateable
= TRUE
;
1727 gp
= _bfd_get_gp_value (output_bfd
);
1731 relocateable
= FALSE
;
1732 output_bfd
= symbol
->section
->output_section
->owner
;
1734 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
,
1735 error_message
, &gp
);
1736 if (ret
!= bfd_reloc_ok
)
1740 if (bfd_is_com_section (symbol
->section
))
1743 relocation
= symbol
->value
;
1745 relocation
+= symbol
->section
->output_section
->vma
;
1746 relocation
+= symbol
->section
->output_offset
;
1748 if (reloc_entry
->address
> input_section
->_cooked_size
)
1749 return bfd_reloc_outofrange
;
1751 if (reloc_entry
->howto
->src_mask
== 0)
1753 /* This case arises with the 64-bit MIPS ELF ABI. */
1757 val
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1759 /* Set val to the offset into the section or symbol. */
1760 val
+= reloc_entry
->addend
;
1762 /* Adjust val for the final section location and GP value. If we
1763 are producing relocateable output, we don't want to do this for
1764 an external symbol. */
1766 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1767 val
+= relocation
- gp
;
1769 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
1772 reloc_entry
->address
+= input_section
->output_offset
;
1774 return bfd_reloc_ok
;
1777 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1778 the rest is at bits 6-10. The bitpos already got right by the howto. */
1780 static bfd_reloc_status_type
1781 mips_elf64_shift6_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1782 output_bfd
, error_message
)
1783 bfd
*abfd ATTRIBUTE_UNUSED
;
1784 arelent
*reloc_entry
;
1786 PTR data ATTRIBUTE_UNUSED
;
1787 asection
*input_section
;
1789 char **error_message ATTRIBUTE_UNUSED
;
1791 /* If we're relocating, and this is an external symbol, we don't
1792 want to change anything. */
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
;
1802 reloc_entry
->addend
= (reloc_entry
->addend
& 0x00007c0)
1803 | (reloc_entry
->addend
& 0x00000800) >> 9;
1805 return bfd_reloc_continue
;
1808 /* Handle a mips16 jump. */
1810 static bfd_reloc_status_type
1811 mips16_jump_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1812 output_bfd
, error_message
)
1813 bfd
*abfd ATTRIBUTE_UNUSED
;
1814 arelent
*reloc_entry
;
1816 PTR data ATTRIBUTE_UNUSED
;
1817 asection
*input_section
;
1819 char **error_message ATTRIBUTE_UNUSED
;
1821 if (output_bfd
!= (bfd
*) NULL
1822 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1823 && (! reloc_entry
->howto
->partial_inplace
1824 || reloc_entry
->addend
== 0))
1826 reloc_entry
->address
+= input_section
->output_offset
;
1827 return bfd_reloc_ok
;
1832 static bfd_boolean warned
;
1835 (*_bfd_error_handler
)
1836 (_("Linking mips16 objects into %s format is not supported"),
1837 bfd_get_target (input_section
->output_section
->owner
));
1841 return bfd_reloc_undefined
;
1844 /* Handle a mips16 GP relative reloc. */
1846 static bfd_reloc_status_type
1847 mips16_gprel_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1848 output_bfd
, error_message
)
1850 arelent
*reloc_entry
;
1853 asection
*input_section
;
1855 char **error_message
;
1857 bfd_boolean relocateable
;
1858 bfd_reloc_status_type ret
;
1860 unsigned short extend
, insn
;
1861 unsigned long final
;
1863 /* If we're relocating, and this is an external symbol with no
1864 addend, we don't want to change anything. We will only have an
1865 addend if this is a newly created reloc, not read from an ELF
1867 if (output_bfd
!= NULL
1868 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1869 && reloc_entry
->addend
== 0)
1871 reloc_entry
->address
+= input_section
->output_offset
;
1872 return bfd_reloc_ok
;
1875 if (output_bfd
!= NULL
)
1876 relocateable
= TRUE
;
1879 relocateable
= FALSE
;
1880 output_bfd
= symbol
->section
->output_section
->owner
;
1883 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1885 if (ret
!= bfd_reloc_ok
)
1888 if (reloc_entry
->address
> input_section
->_cooked_size
)
1889 return bfd_reloc_outofrange
;
1891 /* Pick up the mips16 extend instruction and the real instruction. */
1892 extend
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1893 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1895 /* Stuff the current addend back as a 32 bit value, do the usual
1896 relocation, and then clean up. */
1898 (bfd_vma
) (((extend
& 0x1f) << 11)
1901 (bfd_byte
*) data
+ reloc_entry
->address
);
1903 ret
= _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1904 input_section
, relocateable
, data
, gp
);
1906 final
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1908 (bfd_vma
) ((extend
& 0xf800)
1909 | ((final
>> 11) & 0x1f)
1911 (bfd_byte
*) data
+ reloc_entry
->address
);
1913 (bfd_vma
) ((insn
& 0xffe0)
1915 (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1920 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1922 struct elf_reloc_map
{
1923 bfd_reloc_code_real_type bfd_val
;
1924 enum elf_mips_reloc_type elf_val
;
1927 static const struct elf_reloc_map mips_reloc_map
[] =
1929 { BFD_RELOC_NONE
, R_MIPS_NONE
},
1930 { BFD_RELOC_16
, R_MIPS_16
},
1931 { BFD_RELOC_32
, R_MIPS_32
},
1932 /* There is no BFD reloc for R_MIPS_REL32. */
1933 { BFD_RELOC_64
, R_MIPS_64
},
1934 { BFD_RELOC_CTOR
, R_MIPS_64
},
1935 { BFD_RELOC_16_PCREL
, R_MIPS_PC16
},
1936 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
1937 { BFD_RELOC_LO16
, R_MIPS_LO16
},
1938 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
1939 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
1940 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
1941 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
1942 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
1943 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
1944 { BFD_RELOC_MIPS_SHIFT5
, R_MIPS_SHIFT5
},
1945 { BFD_RELOC_MIPS_SHIFT6
, R_MIPS_SHIFT6
},
1946 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
},
1947 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
1948 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
1949 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
1950 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
1951 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
1952 { BFD_RELOC_MIPS_INSERT_A
, R_MIPS_INSERT_A
},
1953 { BFD_RELOC_MIPS_INSERT_B
, R_MIPS_INSERT_B
},
1954 { BFD_RELOC_MIPS_DELETE
, R_MIPS_DELETE
},
1955 { BFD_RELOC_MIPS_HIGHEST
, R_MIPS_HIGHEST
},
1956 { BFD_RELOC_MIPS_HIGHER
, R_MIPS_HIGHER
},
1957 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
1958 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
1959 { BFD_RELOC_MIPS_SCN_DISP
, R_MIPS_SCN_DISP
},
1960 { BFD_RELOC_MIPS_REL16
, R_MIPS_REL16
},
1961 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1962 { BFD_RELOC_MIPS_RELGOT
, R_MIPS_RELGOT
},
1963 { BFD_RELOC_MIPS_JALR
, R_MIPS_JALR
}
1966 /* Given a BFD reloc type, return a howto structure. */
1968 static reloc_howto_type
*
1969 bfd_elf64_bfd_reloc_type_lookup (abfd
, code
)
1970 bfd
*abfd ATTRIBUTE_UNUSED
;
1971 bfd_reloc_code_real_type code
;
1974 /* FIXME: We default to RELA here instead of choosing the right
1975 relocation variant. */
1976 reloc_howto_type
*howto_table
= mips_elf64_howto_table_rela
;
1978 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
1981 if (mips_reloc_map
[i
].bfd_val
== code
)
1982 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
1987 case BFD_RELOC_MIPS16_JMP
:
1988 return &elf_mips16_jump_howto
;
1989 case BFD_RELOC_MIPS16_GPREL
:
1990 return &elf_mips16_gprel_howto
;
1991 case BFD_RELOC_VTABLE_INHERIT
:
1992 return &elf_mips_gnu_vtinherit_howto
;
1993 case BFD_RELOC_VTABLE_ENTRY
:
1994 return &elf_mips_gnu_vtentry_howto
;
1995 case BFD_RELOC_16_PCREL_S2
:
1996 return &elf_mips_gnu_rela16_s2
;
1998 bfd_set_error (bfd_error_bad_value
);
2003 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2005 static reloc_howto_type
*
2006 mips_elf64_rtype_to_howto (r_type
, rela_p
)
2007 unsigned int r_type
;
2013 return &elf_mips16_jump_howto
;
2014 case R_MIPS16_GPREL
:
2015 return &elf_mips16_gprel_howto
;
2016 case R_MIPS_GNU_VTINHERIT
:
2017 return &elf_mips_gnu_vtinherit_howto
;
2018 case R_MIPS_GNU_VTENTRY
:
2019 return &elf_mips_gnu_vtentry_howto
;
2020 case R_MIPS_GNU_REL16_S2
:
2022 return &elf_mips_gnu_rela16_s2
;
2024 return &elf_mips_gnu_rel16_s2
;
2026 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
2028 return &mips_elf64_howto_table_rela
[r_type
];
2030 return &mips_elf64_howto_table_rel
[r_type
];
2035 /* Prevent relocation handling by bfd for MIPS ELF64. */
2038 mips_elf64_info_to_howto_rel (abfd
, cache_ptr
, dst
)
2039 bfd
*abfd ATTRIBUTE_UNUSED
;
2040 arelent
*cache_ptr ATTRIBUTE_UNUSED
;
2041 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
;
2047 mips_elf64_info_to_howto_rela (abfd
, cache_ptr
, dst
)
2048 bfd
*abfd ATTRIBUTE_UNUSED
;
2049 arelent
*cache_ptr ATTRIBUTE_UNUSED
;
2050 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
;
2055 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2056 to three relocs, we must tell the user to allocate more space. */
2059 mips_elf64_get_reloc_upper_bound (abfd
, sec
)
2060 bfd
*abfd ATTRIBUTE_UNUSED
;
2063 return (sec
->reloc_count
* 3 + 1) * sizeof (arelent
*);
2067 mips_elf64_get_dynamic_reloc_upper_bound (abfd
)
2070 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd
) * 3;
2073 /* We must also copy more relocations than the corresponding functions
2074 in elf.c would, so the two following functions are slightly
2075 modified from elf.c, that multiply the external relocation count by
2076 3 to obtain the internal relocation count. */
2079 mips_elf64_canonicalize_reloc (abfd
, section
, relptr
, symbols
)
2087 struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
2089 if (! bed
->s
->slurp_reloc_table (abfd
, section
, symbols
, FALSE
))
2092 tblptr
= section
->relocation
;
2093 for (i
= 0; i
< section
->reloc_count
* 3; i
++)
2094 *relptr
++ = tblptr
++;
2098 return section
->reloc_count
* 3;
2102 mips_elf64_canonicalize_dynamic_reloc (abfd
, storage
, syms
)
2107 bfd_boolean (*slurp_relocs
)
2108 PARAMS ((bfd
*, asection
*, asymbol
**, bfd_boolean
));
2112 if (elf_dynsymtab (abfd
) == 0)
2114 bfd_set_error (bfd_error_invalid_operation
);
2118 slurp_relocs
= get_elf_backend_data (abfd
)->s
->slurp_reloc_table
;
2120 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
2122 if (elf_section_data (s
)->this_hdr
.sh_link
== elf_dynsymtab (abfd
)
2123 && (elf_section_data (s
)->this_hdr
.sh_type
== SHT_REL
2124 || elf_section_data (s
)->this_hdr
.sh_type
== SHT_RELA
))
2129 if (! (*slurp_relocs
) (abfd
, s
, syms
, TRUE
))
2131 count
= s
->_raw_size
/ elf_section_data (s
)->this_hdr
.sh_entsize
* 3;
2133 for (i
= 0; i
< count
; i
++)
2144 /* Read the relocations from one reloc section. This is mostly copied
2145 from elfcode.h, except for the changes to expand one external
2146 relocation to 3 internal ones. We must unfortunately set
2147 reloc_count to the number of external relocations, because a lot of
2148 generic code seems to depend on this. */
2151 mips_elf64_slurp_one_reloc_table (abfd
, asect
, rel_hdr
, reloc_count
,
2152 relents
, symbols
, dynamic
)
2155 Elf_Internal_Shdr
*rel_hdr
;
2156 bfd_size_type reloc_count
;
2159 bfd_boolean dynamic
;
2161 PTR allocated
= NULL
;
2162 bfd_byte
*native_relocs
;
2166 reloc_howto_type
*howto_table
;
2168 allocated
= (PTR
) bfd_malloc (rel_hdr
->sh_size
);
2169 if (allocated
== NULL
)
2172 if (bfd_seek (abfd
, rel_hdr
->sh_offset
, SEEK_SET
) != 0
2173 || (bfd_bread (allocated
, rel_hdr
->sh_size
, abfd
)
2174 != rel_hdr
->sh_size
))
2177 native_relocs
= (bfd_byte
*) allocated
;
2179 entsize
= rel_hdr
->sh_entsize
;
2180 BFD_ASSERT (entsize
== sizeof (Elf64_Mips_External_Rel
)
2181 || entsize
== sizeof (Elf64_Mips_External_Rela
));
2183 if (entsize
== sizeof (Elf64_Mips_External_Rel
))
2184 howto_table
= mips_elf64_howto_table_rel
;
2186 howto_table
= mips_elf64_howto_table_rela
;
2188 for (i
= 0, relent
= relents
;
2190 i
++, native_relocs
+= entsize
)
2192 Elf64_Mips_Internal_Rela rela
;
2193 bfd_boolean used_sym
, used_ssym
;
2196 if (entsize
== sizeof (Elf64_Mips_External_Rela
))
2197 mips_elf64_swap_reloca_in (abfd
,
2198 (Elf64_Mips_External_Rela
*) native_relocs
,
2201 mips_elf64_swap_reloc_in (abfd
,
2202 (Elf64_Mips_External_Rel
*) native_relocs
,
2205 /* Each entry represents exactly three actual relocations. */
2209 for (ir
= 0; ir
< 3; ir
++)
2211 enum elf_mips_reloc_type type
;
2218 type
= (enum elf_mips_reloc_type
) rela
.r_type
;
2221 type
= (enum elf_mips_reloc_type
) rela
.r_type2
;
2224 type
= (enum elf_mips_reloc_type
) rela
.r_type3
;
2228 /* Some types require symbols, whereas some do not. */
2232 case R_MIPS_LITERAL
:
2233 case R_MIPS_INSERT_A
:
2234 case R_MIPS_INSERT_B
:
2236 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2242 if (rela
.r_sym
== 0)
2243 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2248 ps
= symbols
+ rela
.r_sym
- 1;
2250 if ((s
->flags
& BSF_SECTION_SYM
) == 0)
2251 relent
->sym_ptr_ptr
= ps
;
2253 relent
->sym_ptr_ptr
= s
->section
->symbol_ptr_ptr
;
2258 else if (! used_ssym
)
2260 switch (rela
.r_ssym
)
2263 relent
->sym_ptr_ptr
=
2264 bfd_abs_section_ptr
->symbol_ptr_ptr
;
2270 /* FIXME: I think these need to be handled using
2271 special howto structures. */
2283 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2288 /* The address of an ELF reloc is section relative for an
2289 object file, and absolute for an executable file or
2290 shared library. The address of a BFD reloc is always
2291 section relative. */
2292 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0 || dynamic
)
2293 relent
->address
= rela
.r_offset
;
2295 relent
->address
= rela
.r_offset
- asect
->vma
;
2297 relent
->addend
= rela
.r_addend
;
2299 relent
->howto
= &howto_table
[(int) type
];
2305 asect
->reloc_count
+= (relent
- relents
) / 3;
2307 if (allocated
!= NULL
)
2313 if (allocated
!= NULL
)
2318 /* Read the relocations. On Irix 6, there can be two reloc sections
2319 associated with a single data section. This is copied from
2320 elfcode.h as well, with changes as small as accounting for 3
2321 internal relocs per external reloc and resetting reloc_count to
2322 zero before processing the relocs of a section. */
2325 mips_elf64_slurp_reloc_table (abfd
, asect
, symbols
, dynamic
)
2329 bfd_boolean dynamic
;
2331 struct bfd_elf_section_data
* const d
= elf_section_data (asect
);
2332 Elf_Internal_Shdr
*rel_hdr
;
2333 Elf_Internal_Shdr
*rel_hdr2
;
2334 bfd_size_type reloc_count
;
2335 bfd_size_type reloc_count2
;
2339 if (asect
->relocation
!= NULL
)
2344 if ((asect
->flags
& SEC_RELOC
) == 0
2345 || asect
->reloc_count
== 0)
2348 rel_hdr
= &d
->rel_hdr
;
2349 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2350 rel_hdr2
= d
->rel_hdr2
;
2351 reloc_count2
= (rel_hdr2
? NUM_SHDR_ENTRIES (rel_hdr2
) : 0);
2353 BFD_ASSERT (asect
->reloc_count
== reloc_count
+ reloc_count2
);
2354 BFD_ASSERT (asect
->rel_filepos
== rel_hdr
->sh_offset
2355 || (rel_hdr2
&& asect
->rel_filepos
== rel_hdr2
->sh_offset
));
2360 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2361 case because relocations against this section may use the
2362 dynamic symbol table, and in that case bfd_section_from_shdr
2363 in elf.c does not update the RELOC_COUNT. */
2364 if (asect
->_raw_size
== 0)
2367 rel_hdr
= &d
->this_hdr
;
2368 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2373 /* Allocate space for 3 arelent structures for each Rel structure. */
2374 amt
= (reloc_count
+ reloc_count2
) * 3 * sizeof (arelent
);
2375 relents
= (arelent
*) bfd_alloc (abfd
, amt
);
2376 if (relents
== NULL
)
2379 /* The slurp_one_reloc_table routine increments reloc_count. */
2380 asect
->reloc_count
= 0;
2382 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2383 rel_hdr
, reloc_count
,
2387 if (d
->rel_hdr2
!= NULL
)
2389 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2390 rel_hdr2
, reloc_count2
,
2391 relents
+ reloc_count
* 3,
2396 asect
->relocation
= relents
;
2400 /* Write out the relocations. */
2403 mips_elf64_write_relocs (abfd
, sec
, data
)
2408 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2410 Elf_Internal_Shdr
*rel_hdr
;
2413 /* If we have already failed, don't do anything. */
2417 if ((sec
->flags
& SEC_RELOC
) == 0)
2420 /* The linker backend writes the relocs out itself, and sets the
2421 reloc_count field to zero to inhibit writing them here. Also,
2422 sometimes the SEC_RELOC flag gets set even when there aren't any
2424 if (sec
->reloc_count
== 0)
2427 /* We can combine up to three relocs that refer to the same address
2428 if the latter relocs have no associated symbol. */
2430 for (idx
= 0; idx
< sec
->reloc_count
; idx
++)
2437 addr
= sec
->orelocation
[idx
]->address
;
2438 for (i
= 0; i
< 2; i
++)
2442 if (idx
+ 1 >= sec
->reloc_count
)
2444 r
= sec
->orelocation
[idx
+ 1];
2445 if (r
->address
!= addr
2446 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2447 || (*r
->sym_ptr_ptr
)->value
!= 0)
2450 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2456 rel_hdr
= &elf_section_data (sec
)->rel_hdr
;
2458 /* Do the actual relocation. */
2460 if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rel
))
2461 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, &count
, data
);
2462 else if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rela
))
2463 mips_elf64_write_rela (abfd
, sec
, rel_hdr
, &count
, data
);
2469 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, count
, data
)
2472 Elf_Internal_Shdr
*rel_hdr
;
2476 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2477 Elf64_Mips_External_Rel
*ext_rel
;
2479 asymbol
*last_sym
= 0;
2480 int last_sym_idx
= 0;
2482 rel_hdr
->sh_size
= (bfd_vma
)(rel_hdr
->sh_entsize
* *count
);
2483 rel_hdr
->contents
= (PTR
) bfd_alloc (abfd
, rel_hdr
->sh_size
);
2484 if (rel_hdr
->contents
== NULL
)
2490 ext_rel
= (Elf64_Mips_External_Rel
*) rel_hdr
->contents
;
2491 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rel
++)
2494 Elf64_Mips_Internal_Rela int_rel
;
2499 ptr
= sec
->orelocation
[idx
];
2501 /* The address of an ELF reloc is section relative for an object
2502 file, and absolute for an executable file or shared library.
2503 The address of a BFD reloc is always section relative. */
2504 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2505 int_rel
.r_offset
= ptr
->address
;
2507 int_rel
.r_offset
= ptr
->address
+ sec
->vma
;
2509 sym
= *ptr
->sym_ptr_ptr
;
2510 if (sym
== last_sym
)
2515 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2525 int_rel
.r_ssym
= RSS_UNDEF
;
2527 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2528 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2534 int_rel
.r_type
= ptr
->howto
->type
;
2535 int_rel
.r_type2
= (int) R_MIPS_NONE
;
2536 int_rel
.r_type3
= (int) R_MIPS_NONE
;
2538 for (i
= 0; i
< 2; i
++)
2542 if (idx
+ 1 >= sec
->reloc_count
)
2544 r
= sec
->orelocation
[idx
+ 1];
2545 if (r
->address
!= ptr
->address
2546 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2547 || (*r
->sym_ptr_ptr
)->value
!= 0)
2550 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2553 int_rel
.r_type2
= r
->howto
->type
;
2555 int_rel
.r_type3
= r
->howto
->type
;
2560 mips_elf64_swap_reloc_out (abfd
, &int_rel
, ext_rel
);
2563 BFD_ASSERT (ext_rel
- (Elf64_Mips_External_Rel
*) rel_hdr
->contents
2568 mips_elf64_write_rela (abfd
, sec
, rela_hdr
, count
, data
)
2571 Elf_Internal_Shdr
*rela_hdr
;
2575 bfd_boolean
*failedp
= (bfd_boolean
*) data
;
2576 Elf64_Mips_External_Rela
*ext_rela
;
2578 asymbol
*last_sym
= 0;
2579 int last_sym_idx
= 0;
2581 rela_hdr
->sh_size
= (bfd_vma
)(rela_hdr
->sh_entsize
* *count
);
2582 rela_hdr
->contents
= (PTR
) bfd_alloc (abfd
, rela_hdr
->sh_size
);
2583 if (rela_hdr
->contents
== NULL
)
2589 ext_rela
= (Elf64_Mips_External_Rela
*) rela_hdr
->contents
;
2590 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rela
++)
2593 Elf64_Mips_Internal_Rela int_rela
;
2598 ptr
= sec
->orelocation
[idx
];
2600 /* The address of an ELF reloc is section relative for an object
2601 file, and absolute for an executable file or shared library.
2602 The address of a BFD reloc is always section relative. */
2603 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2604 int_rela
.r_offset
= ptr
->address
;
2606 int_rela
.r_offset
= ptr
->address
+ sec
->vma
;
2608 sym
= *ptr
->sym_ptr_ptr
;
2609 if (sym
== last_sym
)
2614 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2624 int_rela
.r_addend
= ptr
->addend
;
2625 int_rela
.r_ssym
= RSS_UNDEF
;
2627 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2628 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2634 int_rela
.r_type
= ptr
->howto
->type
;
2635 int_rela
.r_type2
= (int) R_MIPS_NONE
;
2636 int_rela
.r_type3
= (int) R_MIPS_NONE
;
2638 for (i
= 0; i
< 2; i
++)
2642 if (idx
+ 1 >= sec
->reloc_count
)
2644 r
= sec
->orelocation
[idx
+ 1];
2645 if (r
->address
!= ptr
->address
2646 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2647 || (*r
->sym_ptr_ptr
)->value
!= 0)
2650 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2653 int_rela
.r_type2
= r
->howto
->type
;
2655 int_rela
.r_type3
= r
->howto
->type
;
2660 mips_elf64_swap_reloca_out (abfd
, &int_rela
, ext_rela
);
2663 BFD_ASSERT (ext_rela
- (Elf64_Mips_External_Rela
*) rela_hdr
->contents
2667 /* Set the right machine number for a MIPS ELF file. */
2670 mips_elf64_object_p (abfd
)
2675 /* Irix 6 is broken. Object file symbol tables are not always
2676 sorted correctly such that local symbols precede global symbols,
2677 and the sh_info field in the symbol table is not always right. */
2678 if (elf64_mips_irix_compat (abfd
) != ict_none
)
2679 elf_bad_symtab (abfd
) = TRUE
;
2681 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
2682 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
2686 /* Depending on the target vector we generate some version of Irix
2687 executables or "normal" MIPS ELF ABI executables. */
2688 static irix_compat_t
2689 elf64_mips_irix_compat (abfd
)
2692 if ((abfd
->xvec
== &bfd_elf64_bigmips_vec
)
2693 || (abfd
->xvec
== &bfd_elf64_littlemips_vec
))
2699 /* Support for core dump NOTE sections. */
2701 elf64_mips_grok_prstatus (abfd
, note
)
2703 Elf_Internal_Note
*note
;
2706 unsigned int raw_size
;
2708 switch (note
->descsz
)
2713 case 480: /* Linux/MIPS - N64 kernel */
2715 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
2718 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 32);
2727 /* Make a ".reg/999" section. */
2728 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
2729 raw_size
, note
->descpos
+ offset
);
2733 elf64_mips_grok_psinfo (abfd
, note
)
2735 Elf_Internal_Note
*note
;
2737 switch (note
->descsz
)
2742 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2743 elf_tdata (abfd
)->core_program
2744 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
2745 elf_tdata (abfd
)->core_command
2746 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
2749 /* Note that for some reason, a spurious space is tacked
2750 onto the end of the args in some (at least one anyway)
2751 implementations, so strip it off if it exists. */
2754 char *command
= elf_tdata (abfd
)->core_command
;
2755 int n
= strlen (command
);
2757 if (0 < n
&& command
[n
- 1] == ' ')
2758 command
[n
- 1] = '\0';
2764 /* ECOFF swapping routines. These are used when dealing with the
2765 .mdebug section, which is in the ECOFF debugging format. */
2766 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap
=
2768 /* Symbol table magic number. */
2770 /* Alignment of debugging information. E.g., 4. */
2772 /* Sizes of external symbolic information. */
2773 sizeof (struct hdr_ext
),
2774 sizeof (struct dnr_ext
),
2775 sizeof (struct pdr_ext
),
2776 sizeof (struct sym_ext
),
2777 sizeof (struct opt_ext
),
2778 sizeof (struct fdr_ext
),
2779 sizeof (struct rfd_ext
),
2780 sizeof (struct ext_ext
),
2781 /* Functions to swap in external symbolic data. */
2790 _bfd_ecoff_swap_tir_in
,
2791 _bfd_ecoff_swap_rndx_in
,
2792 /* Functions to swap out external symbolic data. */
2801 _bfd_ecoff_swap_tir_out
,
2802 _bfd_ecoff_swap_rndx_out
,
2803 /* Function to read in symbolic data. */
2804 _bfd_mips_elf_read_ecoff_info
2807 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2808 standard ELF. This structure is used to redirect the relocation
2809 handling routines. */
2811 const struct elf_size_info mips_elf64_size_info
=
2813 sizeof (Elf64_External_Ehdr
),
2814 sizeof (Elf64_External_Phdr
),
2815 sizeof (Elf64_External_Shdr
),
2816 sizeof (Elf64_Mips_External_Rel
),
2817 sizeof (Elf64_Mips_External_Rela
),
2818 sizeof (Elf64_External_Sym
),
2819 sizeof (Elf64_External_Dyn
),
2820 sizeof (Elf_External_Note
),
2821 4, /* hash-table entry size */
2822 3, /* internal relocations per external relocations */
2824 3, /* log_file_align */
2827 bfd_elf64_write_out_phdrs
,
2828 bfd_elf64_write_shdrs_and_ehdr
,
2829 mips_elf64_write_relocs
,
2830 bfd_elf64_swap_symbol_in
,
2831 bfd_elf64_swap_symbol_out
,
2832 mips_elf64_slurp_reloc_table
,
2833 bfd_elf64_slurp_symbol_table
,
2834 bfd_elf64_swap_dyn_in
,
2835 bfd_elf64_swap_dyn_out
,
2836 mips_elf64_be_swap_reloc_in
,
2837 mips_elf64_be_swap_reloc_out
,
2838 mips_elf64_be_swap_reloca_in
,
2839 mips_elf64_be_swap_reloca_out
2842 #define ELF_ARCH bfd_arch_mips
2843 #define ELF_MACHINE_CODE EM_MIPS
2845 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2846 a value of 0x1000, and we are compatible.
2847 FIXME: How does this affect NewABI? */
2848 #define ELF_MAXPAGESIZE 0x1000
2850 #define elf_backend_collect TRUE
2851 #define elf_backend_type_change_ok TRUE
2852 #define elf_backend_can_gc_sections TRUE
2853 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2854 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2855 #define elf_backend_object_p mips_elf64_object_p
2856 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2857 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2858 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2859 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2860 #define elf_backend_section_from_bfd_section \
2861 _bfd_mips_elf_section_from_bfd_section
2862 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2863 #define elf_backend_link_output_symbol_hook \
2864 _bfd_mips_elf_link_output_symbol_hook
2865 #define elf_backend_create_dynamic_sections \
2866 _bfd_mips_elf_create_dynamic_sections
2867 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2868 #define elf_backend_adjust_dynamic_symbol \
2869 _bfd_mips_elf_adjust_dynamic_symbol
2870 #define elf_backend_always_size_sections \
2871 _bfd_mips_elf_always_size_sections
2872 #define elf_backend_size_dynamic_sections \
2873 _bfd_mips_elf_size_dynamic_sections
2874 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2875 #define elf_backend_finish_dynamic_symbol \
2876 _bfd_mips_elf_finish_dynamic_symbol
2877 #define elf_backend_finish_dynamic_sections \
2878 _bfd_mips_elf_finish_dynamic_sections
2879 #define elf_backend_final_write_processing \
2880 _bfd_mips_elf_final_write_processing
2881 #define elf_backend_additional_program_headers \
2882 _bfd_mips_elf_additional_program_headers
2883 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2884 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2885 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2886 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2887 #define elf_backend_ignore_discarded_relocs \
2888 _bfd_mips_elf_ignore_discarded_relocs
2889 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2890 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2891 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2892 #define elf_backend_size_info mips_elf64_size_info
2894 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
2895 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
2897 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2898 #define elf_backend_plt_header_size 0
2900 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2901 work better/work only in RELA, so we default to this. */
2902 #define elf_backend_may_use_rel_p 1
2903 #define elf_backend_may_use_rela_p 1
2904 #define elf_backend_default_use_rela_p 1
2906 #define elf_backend_write_section _bfd_mips_elf_write_section
2908 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2909 MIPS-specific function only applies to IRIX5, which had no 64-bit
2911 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2912 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
2913 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2914 #define bfd_elf64_bfd_get_relocated_section_contents \
2915 _bfd_elf_mips_get_relocated_section_contents
2916 #define bfd_elf64_bfd_link_hash_table_create \
2917 _bfd_mips_elf_link_hash_table_create
2918 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2919 #define bfd_elf64_bfd_merge_private_bfd_data \
2920 _bfd_mips_elf_merge_private_bfd_data
2921 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2922 #define bfd_elf64_bfd_print_private_bfd_data \
2923 _bfd_mips_elf_print_private_bfd_data
2925 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2926 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
2927 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
2928 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
2929 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
2931 /* MIPS ELF64 archive functions. */
2932 #define bfd_elf64_archive_functions
2933 extern bfd_boolean bfd_elf64_archive_slurp_armap
2935 extern bfd_boolean bfd_elf64_archive_write_armap
2936 PARAMS ((bfd
*, unsigned int, struct orl
*, unsigned int, int));
2937 #define bfd_elf64_archive_slurp_extended_name_table \
2938 _bfd_archive_coff_slurp_extended_name_table
2939 #define bfd_elf64_archive_construct_extended_name_table \
2940 _bfd_archive_coff_construct_extended_name_table
2941 #define bfd_elf64_archive_truncate_arname \
2942 _bfd_archive_coff_truncate_arname
2943 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2944 #define bfd_elf64_archive_openr_next_archived_file \
2945 _bfd_archive_coff_openr_next_archived_file
2946 #define bfd_elf64_archive_get_elt_at_index \
2947 _bfd_archive_coff_get_elt_at_index
2948 #define bfd_elf64_archive_generic_stat_arch_elt \
2949 _bfd_archive_coff_generic_stat_arch_elt
2950 #define bfd_elf64_archive_update_armap_timestamp \
2951 _bfd_archive_coff_update_armap_timestamp
2953 /* The SGI style (n)64 NewABI. */
2954 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2955 #define TARGET_LITTLE_NAME "elf64-littlemips"
2956 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2957 #define TARGET_BIG_NAME "elf64-bigmips"
2959 #include "elf64-target.h"
2961 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2963 /* The SYSV-style 'traditional' (n)64 NewABI. */
2964 #undef TARGET_LITTLE_SYM
2965 #undef TARGET_LITTLE_NAME
2966 #undef TARGET_BIG_SYM
2967 #undef TARGET_BIG_NAME
2969 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2970 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2971 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2972 #define TARGET_BIG_NAME "elf64-tradbigmips"
2974 /* Include the target file again for this target. */
2975 #include "elf64-target.h"