1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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 (bfd
*, const Elf64_Mips_External_Rel
*, Elf64_Mips_Internal_Rela
*);
66 static void mips_elf64_swap_reloca_in
67 (bfd
*, const Elf64_Mips_External_Rela
*, Elf64_Mips_Internal_Rela
*);
68 static void mips_elf64_swap_reloc_out
69 (bfd
*, const Elf64_Mips_Internal_Rela
*, Elf64_Mips_External_Rel
*);
70 static void mips_elf64_swap_reloca_out
71 (bfd
*, const Elf64_Mips_Internal_Rela
*, Elf64_Mips_External_Rela
*);
72 static void mips_elf64_be_swap_reloc_in
73 (bfd
*, const bfd_byte
*, Elf_Internal_Rela
*);
74 static void mips_elf64_be_swap_reloc_out
75 (bfd
*, const Elf_Internal_Rela
*, bfd_byte
*);
76 static void mips_elf64_be_swap_reloca_in
77 (bfd
*, const bfd_byte
*, Elf_Internal_Rela
*);
78 static void mips_elf64_be_swap_reloca_out
79 (bfd
*, const Elf_Internal_Rela
*, bfd_byte
*);
80 static reloc_howto_type
*bfd_elf64_bfd_reloc_type_lookup
81 (bfd
*, bfd_reloc_code_real_type
);
82 static reloc_howto_type
*mips_elf64_rtype_to_howto
83 (unsigned int, bfd_boolean
);
84 static void mips_elf64_info_to_howto_rel
85 (bfd
*, arelent
*, Elf_Internal_Rela
*);
86 static void mips_elf64_info_to_howto_rela
87 (bfd
*, arelent
*, Elf_Internal_Rela
*);
88 static long mips_elf64_get_reloc_upper_bound
90 static long mips_elf64_canonicalize_reloc
91 (bfd
*, asection
*, arelent
**, asymbol
**);
92 static long mips_elf64_get_dynamic_reloc_upper_bound
94 static long mips_elf64_canonicalize_dynamic_reloc
95 (bfd
*, arelent
**, asymbol
**);
96 static bfd_boolean mips_elf64_slurp_one_reloc_table
97 (bfd
*, asection
*, Elf_Internal_Shdr
*, bfd_size_type
, arelent
*,
98 asymbol
**, bfd_boolean
);
99 static bfd_boolean mips_elf64_slurp_reloc_table
100 (bfd
*, asection
*, asymbol
**, bfd_boolean
);
101 static void mips_elf64_write_relocs
102 (bfd
*, asection
*, void *);
103 static void mips_elf64_write_rel
104 (bfd
*, asection
*, Elf_Internal_Shdr
*, int *, void *);
105 static void mips_elf64_write_rela
106 (bfd
*, asection
*, Elf_Internal_Shdr
*, int *, void *);
107 static bfd_reloc_status_type mips_elf64_gprel16_reloc
108 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
109 static bfd_reloc_status_type mips_elf64_literal_reloc
110 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
111 static bfd_reloc_status_type mips_elf64_gprel32_reloc
112 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
113 static bfd_reloc_status_type mips_elf64_shift6_reloc
114 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
115 static bfd_reloc_status_type mips16_jump_reloc
116 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
117 static bfd_reloc_status_type mips16_gprel_reloc
118 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
119 static bfd_boolean mips_elf64_assign_gp
121 static bfd_reloc_status_type mips_elf64_final_gp
122 (bfd
*, asymbol
*, bfd_boolean
, char **, bfd_vma
*);
123 static bfd_boolean mips_elf64_object_p
125 static irix_compat_t elf64_mips_irix_compat
127 static bfd_boolean elf64_mips_grok_prstatus
128 (bfd
*, Elf_Internal_Note
*);
129 static bfd_boolean elf64_mips_grok_psinfo
130 (bfd
*, Elf_Internal_Note
*);
132 extern const bfd_target bfd_elf64_bigmips_vec
;
133 extern const bfd_target bfd_elf64_littlemips_vec
;
135 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
136 from smaller values. Start with zero, widen, *then* decrement. */
137 #define MINUS_ONE (((bfd_vma)0) - 1)
139 /* The number of local .got entries we reserve. */
140 #define MIPS_RESERVED_GOTNO (2)
142 /* The relocation table used for SHT_REL sections. */
144 static reloc_howto_type mips_elf64_howto_table_rel
[] =
147 HOWTO (R_MIPS_NONE
, /* type */
149 0, /* size (0 = byte, 1 = short, 2 = long) */
151 FALSE
, /* pc_relative */
153 complain_overflow_dont
, /* complain_on_overflow */
154 _bfd_mips_elf_generic_reloc
, /* special_function */
155 "R_MIPS_NONE", /* name */
156 FALSE
, /* partial_inplace */
159 FALSE
), /* pcrel_offset */
161 /* 16 bit relocation. */
162 HOWTO (R_MIPS_16
, /* type */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
166 FALSE
, /* pc_relative */
168 complain_overflow_signed
, /* complain_on_overflow */
169 _bfd_mips_elf_generic_reloc
, /* special_function */
170 "R_MIPS_16", /* name */
171 TRUE
, /* partial_inplace */
172 0x0000ffff, /* src_mask */
173 0x0000ffff, /* dst_mask */
174 FALSE
), /* pcrel_offset */
176 /* 32 bit relocation. */
177 HOWTO (R_MIPS_32
, /* type */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
181 FALSE
, /* pc_relative */
183 complain_overflow_dont
, /* complain_on_overflow */
184 _bfd_mips_elf_generic_reloc
, /* special_function */
185 "R_MIPS_32", /* name */
186 TRUE
, /* partial_inplace */
187 0xffffffff, /* src_mask */
188 0xffffffff, /* dst_mask */
189 FALSE
), /* pcrel_offset */
191 /* 32 bit symbol relative relocation. */
192 HOWTO (R_MIPS_REL32
, /* type */
194 2, /* size (0 = byte, 1 = short, 2 = long) */
196 FALSE
, /* pc_relative */
198 complain_overflow_dont
, /* complain_on_overflow */
199 _bfd_mips_elf_generic_reloc
, /* special_function */
200 "R_MIPS_REL32", /* name */
201 TRUE
, /* partial_inplace */
202 0xffffffff, /* src_mask */
203 0xffffffff, /* dst_mask */
204 FALSE
), /* pcrel_offset */
206 /* 26 bit jump address. */
207 HOWTO (R_MIPS_26
, /* type */
209 2, /* size (0 = byte, 1 = short, 2 = long) */
211 FALSE
, /* pc_relative */
213 complain_overflow_dont
, /* complain_on_overflow */
214 /* This needs complex overflow
215 detection, because the upper 36
216 bits must match the PC + 4. */
217 _bfd_mips_elf_generic_reloc
, /* special_function */
218 "R_MIPS_26", /* name */
219 TRUE
, /* partial_inplace */
220 0x03ffffff, /* src_mask */
221 0x03ffffff, /* dst_mask */
222 FALSE
), /* pcrel_offset */
224 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
225 However, the native IRIX6 tools use them, so we try our best. */
227 /* High 16 bits of symbol value. */
228 HOWTO (R_MIPS_HI16
, /* type */
230 2, /* size (0 = byte, 1 = short, 2 = long) */
232 FALSE
, /* pc_relative */
234 complain_overflow_dont
, /* complain_on_overflow */
235 _bfd_mips_elf_hi16_reloc
, /* special_function */
236 "R_MIPS_HI16", /* name */
237 TRUE
, /* partial_inplace */
238 0x0000ffff, /* src_mask */
239 0x0000ffff, /* dst_mask */
240 FALSE
), /* pcrel_offset */
242 /* Low 16 bits of symbol value. */
243 HOWTO (R_MIPS_LO16
, /* type */
245 2, /* size (0 = byte, 1 = short, 2 = long) */
247 FALSE
, /* pc_relative */
249 complain_overflow_dont
, /* complain_on_overflow */
250 _bfd_mips_elf_lo16_reloc
, /* special_function */
251 "R_MIPS_LO16", /* name */
252 TRUE
, /* partial_inplace */
253 0x0000ffff, /* src_mask */
254 0x0000ffff, /* dst_mask */
255 FALSE
), /* pcrel_offset */
257 /* GP relative reference. */
258 HOWTO (R_MIPS_GPREL16
, /* type */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
262 FALSE
, /* pc_relative */
264 complain_overflow_signed
, /* complain_on_overflow */
265 mips_elf64_gprel16_reloc
, /* special_function */
266 "R_MIPS_GPREL16", /* name */
267 TRUE
, /* partial_inplace */
268 0x0000ffff, /* src_mask */
269 0x0000ffff, /* dst_mask */
270 FALSE
), /* pcrel_offset */
272 /* Reference to literal section. */
273 HOWTO (R_MIPS_LITERAL
, /* type */
275 2, /* size (0 = byte, 1 = short, 2 = long) */
277 FALSE
, /* pc_relative */
279 complain_overflow_signed
, /* complain_on_overflow */
280 mips_elf64_literal_reloc
, /* special_function */
281 "R_MIPS_LITERAL", /* name */
282 TRUE
, /* partial_inplace */
283 0x0000ffff, /* src_mask */
284 0x0000ffff, /* dst_mask */
285 FALSE
), /* pcrel_offset */
287 /* Reference to global offset table. */
288 HOWTO (R_MIPS_GOT16
, /* type */
290 2, /* size (0 = byte, 1 = short, 2 = long) */
292 FALSE
, /* pc_relative */
294 complain_overflow_signed
, /* complain_on_overflow */
295 _bfd_mips_elf_got16_reloc
, /* special_function */
296 "R_MIPS_GOT16", /* name */
297 TRUE
, /* partial_inplace */
298 0x0000ffff, /* src_mask */
299 0x0000ffff, /* dst_mask */
300 FALSE
), /* pcrel_offset */
302 /* 16 bit PC relative reference. */
303 HOWTO (R_MIPS_PC16
, /* type */
305 2, /* size (0 = byte, 1 = short, 2 = long) */
307 TRUE
, /* pc_relative */
309 complain_overflow_signed
, /* complain_on_overflow */
310 _bfd_mips_elf_generic_reloc
, /* special_function */
311 "R_MIPS_PC16", /* name */
312 TRUE
, /* partial_inplace */
313 0x0000ffff, /* src_mask */
314 0x0000ffff, /* dst_mask */
315 TRUE
), /* pcrel_offset */
317 /* 16 bit call through global offset table. */
318 HOWTO (R_MIPS_CALL16
, /* type */
320 2, /* size (0 = byte, 1 = short, 2 = long) */
322 FALSE
, /* pc_relative */
324 complain_overflow_signed
, /* complain_on_overflow */
325 _bfd_mips_elf_generic_reloc
, /* special_function */
326 "R_MIPS_CALL16", /* name */
327 TRUE
, /* partial_inplace */
328 0x0000ffff, /* src_mask */
329 0x0000ffff, /* dst_mask */
330 FALSE
), /* pcrel_offset */
332 /* 32 bit GP relative reference. */
333 HOWTO (R_MIPS_GPREL32
, /* type */
335 2, /* size (0 = byte, 1 = short, 2 = long) */
337 FALSE
, /* pc_relative */
339 complain_overflow_dont
, /* complain_on_overflow */
340 mips_elf64_gprel32_reloc
, /* special_function */
341 "R_MIPS_GPREL32", /* name */
342 TRUE
, /* partial_inplace */
343 0xffffffff, /* src_mask */
344 0xffffffff, /* dst_mask */
345 FALSE
), /* pcrel_offset */
351 /* A 5 bit shift field. */
352 HOWTO (R_MIPS_SHIFT5
, /* type */
354 2, /* size (0 = byte, 1 = short, 2 = long) */
356 FALSE
, /* pc_relative */
358 complain_overflow_bitfield
, /* complain_on_overflow */
359 _bfd_mips_elf_generic_reloc
, /* special_function */
360 "R_MIPS_SHIFT5", /* name */
361 TRUE
, /* partial_inplace */
362 0x000007c0, /* src_mask */
363 0x000007c0, /* dst_mask */
364 FALSE
), /* pcrel_offset */
366 /* A 6 bit shift field. */
367 HOWTO (R_MIPS_SHIFT6
, /* type */
369 2, /* size (0 = byte, 1 = short, 2 = long) */
371 FALSE
, /* pc_relative */
373 complain_overflow_bitfield
, /* complain_on_overflow */
374 mips_elf64_shift6_reloc
, /* special_function */
375 "R_MIPS_SHIFT6", /* name */
376 TRUE
, /* partial_inplace */
377 0x000007c4, /* src_mask */
378 0x000007c4, /* dst_mask */
379 FALSE
), /* pcrel_offset */
381 /* 64 bit relocation. */
382 HOWTO (R_MIPS_64
, /* type */
384 4, /* size (0 = byte, 1 = short, 2 = long) */
386 FALSE
, /* pc_relative */
388 complain_overflow_dont
, /* complain_on_overflow */
389 _bfd_mips_elf_generic_reloc
, /* special_function */
390 "R_MIPS_64", /* name */
391 TRUE
, /* partial_inplace */
392 MINUS_ONE
, /* src_mask */
393 MINUS_ONE
, /* dst_mask */
394 FALSE
), /* pcrel_offset */
396 /* Displacement in the global offset table. */
397 HOWTO (R_MIPS_GOT_DISP
, /* type */
399 2, /* size (0 = byte, 1 = short, 2 = long) */
401 FALSE
, /* pc_relative */
403 complain_overflow_signed
, /* complain_on_overflow */
404 _bfd_mips_elf_generic_reloc
, /* special_function */
405 "R_MIPS_GOT_DISP", /* name */
406 TRUE
, /* partial_inplace */
407 0x0000ffff, /* src_mask */
408 0x0000ffff, /* dst_mask */
409 FALSE
), /* pcrel_offset */
411 /* Displacement to page pointer in the global offset table. */
412 HOWTO (R_MIPS_GOT_PAGE
, /* type */
414 2, /* size (0 = byte, 1 = short, 2 = long) */
416 FALSE
, /* pc_relative */
418 complain_overflow_signed
, /* complain_on_overflow */
419 _bfd_mips_elf_generic_reloc
, /* special_function */
420 "R_MIPS_GOT_PAGE", /* name */
421 TRUE
, /* partial_inplace */
422 0x0000ffff, /* src_mask */
423 0x0000ffff, /* dst_mask */
424 FALSE
), /* pcrel_offset */
426 /* Offset from page pointer in the global offset table. */
427 HOWTO (R_MIPS_GOT_OFST
, /* type */
429 2, /* size (0 = byte, 1 = short, 2 = long) */
431 FALSE
, /* pc_relative */
433 complain_overflow_signed
, /* complain_on_overflow */
434 _bfd_mips_elf_generic_reloc
, /* special_function */
435 "R_MIPS_GOT_OFST", /* name */
436 TRUE
, /* partial_inplace */
437 0x0000ffff, /* src_mask */
438 0x0000ffff, /* dst_mask */
439 FALSE
), /* pcrel_offset */
441 /* High 16 bits of displacement in global offset table. */
442 HOWTO (R_MIPS_GOT_HI16
, /* type */
444 2, /* size (0 = byte, 1 = short, 2 = long) */
446 FALSE
, /* pc_relative */
448 complain_overflow_dont
, /* complain_on_overflow */
449 _bfd_mips_elf_generic_reloc
, /* special_function */
450 "R_MIPS_GOT_HI16", /* name */
451 TRUE
, /* partial_inplace */
452 0x0000ffff, /* src_mask */
453 0x0000ffff, /* dst_mask */
454 FALSE
), /* pcrel_offset */
456 /* Low 16 bits of displacement in global offset table. */
457 HOWTO (R_MIPS_GOT_LO16
, /* type */
459 2, /* size (0 = byte, 1 = short, 2 = long) */
461 FALSE
, /* pc_relative */
463 complain_overflow_dont
, /* complain_on_overflow */
464 _bfd_mips_elf_generic_reloc
, /* special_function */
465 "R_MIPS_GOT_LO16", /* name */
466 TRUE
, /* partial_inplace */
467 0x0000ffff, /* src_mask */
468 0x0000ffff, /* dst_mask */
469 FALSE
), /* pcrel_offset */
471 /* 64 bit subtraction. */
472 HOWTO (R_MIPS_SUB
, /* type */
474 4, /* size (0 = byte, 1 = short, 2 = long) */
476 FALSE
, /* pc_relative */
478 complain_overflow_dont
, /* complain_on_overflow */
479 _bfd_mips_elf_generic_reloc
, /* special_function */
480 "R_MIPS_SUB", /* name */
481 TRUE
, /* partial_inplace */
482 MINUS_ONE
, /* src_mask */
483 MINUS_ONE
, /* dst_mask */
484 FALSE
), /* pcrel_offset */
486 /* Insert the addend as an instruction. */
487 /* FIXME: Not handled correctly. */
488 HOWTO (R_MIPS_INSERT_A
, /* type */
490 2, /* size (0 = byte, 1 = short, 2 = long) */
492 FALSE
, /* pc_relative */
494 complain_overflow_dont
, /* complain_on_overflow */
495 _bfd_mips_elf_generic_reloc
, /* special_function */
496 "R_MIPS_INSERT_A", /* name */
497 TRUE
, /* partial_inplace */
498 0xffffffff, /* src_mask */
499 0xffffffff, /* dst_mask */
500 FALSE
), /* pcrel_offset */
502 /* Insert the addend as an instruction, and change all relocations
503 to refer to the old instruction at the address. */
504 /* FIXME: Not handled correctly. */
505 HOWTO (R_MIPS_INSERT_B
, /* type */
507 2, /* size (0 = byte, 1 = short, 2 = long) */
509 FALSE
, /* pc_relative */
511 complain_overflow_dont
, /* complain_on_overflow */
512 _bfd_mips_elf_generic_reloc
, /* special_function */
513 "R_MIPS_INSERT_B", /* name */
514 TRUE
, /* partial_inplace */
515 0xffffffff, /* src_mask */
516 0xffffffff, /* dst_mask */
517 FALSE
), /* pcrel_offset */
519 /* Delete a 32 bit instruction. */
520 /* FIXME: Not handled correctly. */
521 HOWTO (R_MIPS_DELETE
, /* type */
523 2, /* size (0 = byte, 1 = short, 2 = long) */
525 FALSE
, /* pc_relative */
527 complain_overflow_dont
, /* complain_on_overflow */
528 _bfd_mips_elf_generic_reloc
, /* special_function */
529 "R_MIPS_DELETE", /* name */
530 TRUE
, /* partial_inplace */
531 0xffffffff, /* src_mask */
532 0xffffffff, /* dst_mask */
533 FALSE
), /* pcrel_offset */
535 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
537 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
538 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
540 b) No other NewABI toolchain actually emits such relocations. */
541 EMPTY_HOWTO (R_MIPS_HIGHER
),
542 EMPTY_HOWTO (R_MIPS_HIGHEST
),
544 /* High 16 bits of displacement in global offset table. */
545 HOWTO (R_MIPS_CALL_HI16
, /* type */
547 2, /* size (0 = byte, 1 = short, 2 = long) */
549 FALSE
, /* pc_relative */
551 complain_overflow_dont
, /* complain_on_overflow */
552 _bfd_mips_elf_generic_reloc
, /* special_function */
553 "R_MIPS_CALL_HI16", /* name */
554 TRUE
, /* partial_inplace */
555 0x0000ffff, /* src_mask */
556 0x0000ffff, /* dst_mask */
557 FALSE
), /* pcrel_offset */
559 /* Low 16 bits of displacement in global offset table. */
560 HOWTO (R_MIPS_CALL_LO16
, /* type */
562 2, /* size (0 = byte, 1 = short, 2 = long) */
564 FALSE
, /* pc_relative */
566 complain_overflow_dont
, /* complain_on_overflow */
567 _bfd_mips_elf_generic_reloc
, /* special_function */
568 "R_MIPS_CALL_LO16", /* name */
569 TRUE
, /* partial_inplace */
570 0x0000ffff, /* src_mask */
571 0x0000ffff, /* dst_mask */
572 FALSE
), /* pcrel_offset */
574 /* Section displacement, used by an associated event location section. */
575 HOWTO (R_MIPS_SCN_DISP
, /* type */
577 2, /* size (0 = byte, 1 = short, 2 = long) */
579 FALSE
, /* pc_relative */
581 complain_overflow_dont
, /* complain_on_overflow */
582 _bfd_mips_elf_generic_reloc
, /* special_function */
583 "R_MIPS_SCN_DISP", /* name */
584 TRUE
, /* partial_inplace */
585 0xffffffff, /* src_mask */
586 0xffffffff, /* dst_mask */
587 FALSE
), /* pcrel_offset */
589 HOWTO (R_MIPS_REL16
, /* type */
591 1, /* size (0 = byte, 1 = short, 2 = long) */
593 FALSE
, /* pc_relative */
595 complain_overflow_signed
, /* complain_on_overflow */
596 _bfd_mips_elf_generic_reloc
, /* special_function */
597 "R_MIPS_REL16", /* name */
598 TRUE
, /* partial_inplace */
599 0xffff, /* src_mask */
600 0xffff, /* dst_mask */
601 FALSE
), /* pcrel_offset */
603 /* These two are obsolete. */
604 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
605 EMPTY_HOWTO (R_MIPS_PJUMP
),
607 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
608 It must be used for multigot GOT's (and only there). */
609 HOWTO (R_MIPS_RELGOT
, /* type */
611 2, /* size (0 = byte, 1 = short, 2 = long) */
613 FALSE
, /* pc_relative */
615 complain_overflow_dont
, /* complain_on_overflow */
616 _bfd_mips_elf_generic_reloc
, /* special_function */
617 "R_MIPS_RELGOT", /* name */
618 TRUE
, /* partial_inplace */
619 0xffffffff, /* src_mask */
620 0xffffffff, /* dst_mask */
621 FALSE
), /* pcrel_offset */
623 /* Protected jump conversion. This is an optimization hint. No
624 relocation is required for correctness. */
625 HOWTO (R_MIPS_JALR
, /* type */
627 2, /* size (0 = byte, 1 = short, 2 = long) */
629 FALSE
, /* pc_relative */
631 complain_overflow_dont
, /* complain_on_overflow */
632 _bfd_mips_elf_generic_reloc
, /* special_function */
633 "R_MIPS_JALR", /* name */
634 FALSE
, /* partial_inplace */
636 0x00000000, /* dst_mask */
637 FALSE
), /* pcrel_offset */
640 /* The relocation table used for SHT_RELA sections. */
642 static reloc_howto_type mips_elf64_howto_table_rela
[] =
645 HOWTO (R_MIPS_NONE
, /* type */
647 0, /* size (0 = byte, 1 = short, 2 = long) */
649 FALSE
, /* pc_relative */
651 complain_overflow_dont
, /* complain_on_overflow */
652 _bfd_mips_elf_generic_reloc
, /* special_function */
653 "R_MIPS_NONE", /* name */
654 FALSE
, /* partial_inplace */
657 FALSE
), /* pcrel_offset */
659 /* 16 bit relocation. */
660 HOWTO (R_MIPS_16
, /* type */
662 2, /* size (0 = byte, 1 = short, 2 = long) */
664 FALSE
, /* pc_relative */
666 complain_overflow_signed
, /* complain_on_overflow */
667 _bfd_mips_elf_generic_reloc
, /* special_function */
668 "R_MIPS_16", /* name */
669 FALSE
, /* partial_inplace */
671 0x0000ffff, /* dst_mask */
672 FALSE
), /* pcrel_offset */
674 /* 32 bit relocation. */
675 HOWTO (R_MIPS_32
, /* type */
677 2, /* size (0 = byte, 1 = short, 2 = long) */
679 FALSE
, /* pc_relative */
681 complain_overflow_dont
, /* complain_on_overflow */
682 _bfd_mips_elf_generic_reloc
, /* special_function */
683 "R_MIPS_32", /* name */
684 FALSE
, /* partial_inplace */
686 0xffffffff, /* dst_mask */
687 FALSE
), /* pcrel_offset */
689 /* 32 bit symbol relative relocation. */
690 HOWTO (R_MIPS_REL32
, /* type */
692 2, /* size (0 = byte, 1 = short, 2 = long) */
694 FALSE
, /* pc_relative */
696 complain_overflow_dont
, /* complain_on_overflow */
697 _bfd_mips_elf_generic_reloc
, /* special_function */
698 "R_MIPS_REL32", /* name */
699 FALSE
, /* partial_inplace */
701 0xffffffff, /* dst_mask */
702 FALSE
), /* pcrel_offset */
704 /* 26 bit jump address. */
705 HOWTO (R_MIPS_26
, /* type */
707 2, /* size (0 = byte, 1 = short, 2 = long) */
709 FALSE
, /* pc_relative */
711 complain_overflow_dont
, /* complain_on_overflow */
712 /* This needs complex overflow
713 detection, because the upper 36
714 bits must match the PC + 4. */
715 _bfd_mips_elf_generic_reloc
, /* special_function */
716 "R_MIPS_26", /* name */
717 FALSE
, /* partial_inplace */
719 0x03ffffff, /* dst_mask */
720 FALSE
), /* pcrel_offset */
722 /* High 16 bits of symbol value. */
723 HOWTO (R_MIPS_HI16
, /* type */
725 2, /* size (0 = byte, 1 = short, 2 = long) */
727 FALSE
, /* pc_relative */
729 complain_overflow_dont
, /* complain_on_overflow */
730 _bfd_mips_elf_generic_reloc
, /* special_function */
731 "R_MIPS_HI16", /* name */
732 FALSE
, /* partial_inplace */
734 0x0000ffff, /* dst_mask */
735 FALSE
), /* pcrel_offset */
737 /* Low 16 bits of symbol value. */
738 HOWTO (R_MIPS_LO16
, /* type */
740 2, /* size (0 = byte, 1 = short, 2 = long) */
742 FALSE
, /* pc_relative */
744 complain_overflow_dont
, /* complain_on_overflow */
745 _bfd_mips_elf_generic_reloc
, /* special_function */
746 "R_MIPS_LO16", /* name */
747 FALSE
, /* partial_inplace */
749 0x0000ffff, /* dst_mask */
750 FALSE
), /* pcrel_offset */
752 /* GP relative reference. */
753 HOWTO (R_MIPS_GPREL16
, /* type */
755 2, /* size (0 = byte, 1 = short, 2 = long) */
757 FALSE
, /* pc_relative */
759 complain_overflow_signed
, /* complain_on_overflow */
760 mips_elf64_gprel16_reloc
, /* special_function */
761 "R_MIPS_GPREL16", /* name */
762 FALSE
, /* partial_inplace */
764 0x0000ffff, /* dst_mask */
765 FALSE
), /* pcrel_offset */
767 /* Reference to literal section. */
768 HOWTO (R_MIPS_LITERAL
, /* type */
770 2, /* size (0 = byte, 1 = short, 2 = long) */
772 FALSE
, /* pc_relative */
774 complain_overflow_signed
, /* complain_on_overflow */
775 mips_elf64_literal_reloc
, /* special_function */
776 "R_MIPS_LITERAL", /* name */
777 FALSE
, /* partial_inplace */
779 0x0000ffff, /* dst_mask */
780 FALSE
), /* pcrel_offset */
782 /* Reference to global offset table. */
783 HOWTO (R_MIPS_GOT16
, /* type */
785 2, /* size (0 = byte, 1 = short, 2 = long) */
787 FALSE
, /* pc_relative */
789 complain_overflow_signed
, /* complain_on_overflow */
790 _bfd_mips_elf_generic_reloc
, /* special_function */
791 "R_MIPS_GOT16", /* name */
792 FALSE
, /* partial_inplace */
794 0x0000ffff, /* dst_mask */
795 FALSE
), /* pcrel_offset */
797 /* 16 bit PC relative reference. */
798 HOWTO (R_MIPS_PC16
, /* type */
800 2, /* size (0 = byte, 1 = short, 2 = long) */
802 TRUE
, /* pc_relative */
804 complain_overflow_signed
, /* complain_on_overflow */
805 _bfd_mips_elf_generic_reloc
, /* special_function */
806 "R_MIPS_PC16", /* name */
807 FALSE
, /* partial_inplace */
809 0x0000ffff, /* dst_mask */
810 TRUE
), /* pcrel_offset */
812 /* 16 bit call through global offset table. */
813 HOWTO (R_MIPS_CALL16
, /* type */
815 2, /* size (0 = byte, 1 = short, 2 = long) */
817 FALSE
, /* pc_relative */
819 complain_overflow_signed
, /* complain_on_overflow */
820 _bfd_mips_elf_generic_reloc
, /* special_function */
821 "R_MIPS_CALL16", /* name */
822 FALSE
, /* partial_inplace */
824 0x0000ffff, /* dst_mask */
825 FALSE
), /* pcrel_offset */
827 /* 32 bit GP relative reference. */
828 HOWTO (R_MIPS_GPREL32
, /* type */
830 2, /* size (0 = byte, 1 = short, 2 = long) */
832 FALSE
, /* pc_relative */
834 complain_overflow_dont
, /* complain_on_overflow */
835 mips_elf64_gprel32_reloc
, /* special_function */
836 "R_MIPS_GPREL32", /* name */
837 FALSE
, /* partial_inplace */
839 0xffffffff, /* dst_mask */
840 FALSE
), /* pcrel_offset */
846 /* A 5 bit shift field. */
847 HOWTO (R_MIPS_SHIFT5
, /* type */
849 2, /* size (0 = byte, 1 = short, 2 = long) */
851 FALSE
, /* pc_relative */
853 complain_overflow_bitfield
, /* complain_on_overflow */
854 _bfd_mips_elf_generic_reloc
, /* special_function */
855 "R_MIPS_SHIFT5", /* name */
856 FALSE
, /* partial_inplace */
858 0x000007c0, /* dst_mask */
859 FALSE
), /* pcrel_offset */
861 /* A 6 bit shift field. */
862 HOWTO (R_MIPS_SHIFT6
, /* type */
864 2, /* size (0 = byte, 1 = short, 2 = long) */
866 FALSE
, /* pc_relative */
868 complain_overflow_bitfield
, /* complain_on_overflow */
869 mips_elf64_shift6_reloc
, /* special_function */
870 "R_MIPS_SHIFT6", /* name */
871 FALSE
, /* partial_inplace */
873 0x000007c4, /* dst_mask */
874 FALSE
), /* pcrel_offset */
876 /* 64 bit relocation. */
877 HOWTO (R_MIPS_64
, /* type */
879 4, /* size (0 = byte, 1 = short, 2 = long) */
881 FALSE
, /* pc_relative */
883 complain_overflow_dont
, /* complain_on_overflow */
884 _bfd_mips_elf_generic_reloc
, /* special_function */
885 "R_MIPS_64", /* name */
886 FALSE
, /* partial_inplace */
888 MINUS_ONE
, /* dst_mask */
889 FALSE
), /* pcrel_offset */
891 /* Displacement in the global offset table. */
892 HOWTO (R_MIPS_GOT_DISP
, /* type */
894 2, /* size (0 = byte, 1 = short, 2 = long) */
896 FALSE
, /* pc_relative */
898 complain_overflow_signed
, /* complain_on_overflow */
899 _bfd_mips_elf_generic_reloc
, /* special_function */
900 "R_MIPS_GOT_DISP", /* name */
901 FALSE
, /* partial_inplace */
903 0x0000ffff, /* dst_mask */
904 FALSE
), /* pcrel_offset */
906 /* Displacement to page pointer in the global offset table. */
907 HOWTO (R_MIPS_GOT_PAGE
, /* type */
909 2, /* size (0 = byte, 1 = short, 2 = long) */
911 FALSE
, /* pc_relative */
913 complain_overflow_signed
, /* complain_on_overflow */
914 _bfd_mips_elf_generic_reloc
, /* special_function */
915 "R_MIPS_GOT_PAGE", /* name */
916 FALSE
, /* partial_inplace */
918 0x0000ffff, /* dst_mask */
919 FALSE
), /* pcrel_offset */
921 /* Offset from page pointer in the global offset table. */
922 HOWTO (R_MIPS_GOT_OFST
, /* type */
924 2, /* size (0 = byte, 1 = short, 2 = long) */
926 FALSE
, /* pc_relative */
928 complain_overflow_signed
, /* complain_on_overflow */
929 _bfd_mips_elf_generic_reloc
, /* special_function */
930 "R_MIPS_GOT_OFST", /* name */
931 FALSE
, /* partial_inplace */
933 0x0000ffff, /* dst_mask */
934 FALSE
), /* pcrel_offset */
936 /* High 16 bits of displacement in global offset table. */
937 HOWTO (R_MIPS_GOT_HI16
, /* type */
939 2, /* size (0 = byte, 1 = short, 2 = long) */
941 FALSE
, /* pc_relative */
943 complain_overflow_dont
, /* complain_on_overflow */
944 _bfd_mips_elf_generic_reloc
, /* special_function */
945 "R_MIPS_GOT_HI16", /* name */
946 FALSE
, /* partial_inplace */
948 0x0000ffff, /* dst_mask */
949 FALSE
), /* pcrel_offset */
951 /* Low 16 bits of displacement in global offset table. */
952 HOWTO (R_MIPS_GOT_LO16
, /* type */
954 2, /* size (0 = byte, 1 = short, 2 = long) */
956 FALSE
, /* pc_relative */
958 complain_overflow_dont
, /* complain_on_overflow */
959 _bfd_mips_elf_generic_reloc
, /* special_function */
960 "R_MIPS_GOT_LO16", /* name */
961 FALSE
, /* partial_inplace */
963 0x0000ffff, /* dst_mask */
964 FALSE
), /* pcrel_offset */
966 /* 64 bit subtraction. */
967 HOWTO (R_MIPS_SUB
, /* type */
969 4, /* size (0 = byte, 1 = short, 2 = long) */
971 FALSE
, /* pc_relative */
973 complain_overflow_dont
, /* complain_on_overflow */
974 _bfd_mips_elf_generic_reloc
, /* special_function */
975 "R_MIPS_SUB", /* name */
976 FALSE
, /* partial_inplace */
978 MINUS_ONE
, /* dst_mask */
979 FALSE
), /* pcrel_offset */
981 /* Insert the addend as an instruction. */
982 /* FIXME: Not handled correctly. */
983 HOWTO (R_MIPS_INSERT_A
, /* type */
985 2, /* size (0 = byte, 1 = short, 2 = long) */
987 FALSE
, /* pc_relative */
989 complain_overflow_dont
, /* complain_on_overflow */
990 _bfd_mips_elf_generic_reloc
, /* special_function */
991 "R_MIPS_INSERT_A", /* name */
992 FALSE
, /* partial_inplace */
994 0xffffffff, /* dst_mask */
995 FALSE
), /* pcrel_offset */
997 /* Insert the addend as an instruction, and change all relocations
998 to refer to the old instruction at the address. */
999 /* FIXME: Not handled correctly. */
1000 HOWTO (R_MIPS_INSERT_B
, /* type */
1002 2, /* size (0 = byte, 1 = short, 2 = long) */
1004 FALSE
, /* pc_relative */
1006 complain_overflow_dont
, /* complain_on_overflow */
1007 _bfd_mips_elf_generic_reloc
, /* special_function */
1008 "R_MIPS_INSERT_B", /* name */
1009 FALSE
, /* partial_inplace */
1011 0xffffffff, /* dst_mask */
1012 FALSE
), /* pcrel_offset */
1014 /* Delete a 32 bit instruction. */
1015 /* FIXME: Not handled correctly. */
1016 HOWTO (R_MIPS_DELETE
, /* type */
1018 2, /* size (0 = byte, 1 = short, 2 = long) */
1020 FALSE
, /* pc_relative */
1022 complain_overflow_dont
, /* complain_on_overflow */
1023 _bfd_mips_elf_generic_reloc
, /* special_function */
1024 "R_MIPS_DELETE", /* name */
1025 FALSE
, /* partial_inplace */
1027 0xffffffff, /* dst_mask */
1028 FALSE
), /* pcrel_offset */
1030 /* Get the higher value of a 64 bit addend. */
1031 HOWTO (R_MIPS_HIGHER
, /* type */
1033 2, /* size (0 = byte, 1 = short, 2 = long) */
1035 FALSE
, /* pc_relative */
1037 complain_overflow_dont
, /* complain_on_overflow */
1038 _bfd_mips_elf_generic_reloc
, /* special_function */
1039 "R_MIPS_HIGHER", /* name */
1040 FALSE
, /* partial_inplace */
1042 0x0000ffff, /* dst_mask */
1043 FALSE
), /* pcrel_offset */
1045 /* Get the highest value of a 64 bit addend. */
1046 HOWTO (R_MIPS_HIGHEST
, /* type */
1048 2, /* size (0 = byte, 1 = short, 2 = long) */
1050 FALSE
, /* pc_relative */
1052 complain_overflow_dont
, /* complain_on_overflow */
1053 _bfd_mips_elf_generic_reloc
, /* special_function */
1054 "R_MIPS_HIGHEST", /* name */
1055 FALSE
, /* partial_inplace */
1057 0x0000ffff, /* dst_mask */
1058 FALSE
), /* pcrel_offset */
1060 /* High 16 bits of displacement in global offset table. */
1061 HOWTO (R_MIPS_CALL_HI16
, /* type */
1063 2, /* size (0 = byte, 1 = short, 2 = long) */
1065 FALSE
, /* pc_relative */
1067 complain_overflow_dont
, /* complain_on_overflow */
1068 _bfd_mips_elf_generic_reloc
, /* special_function */
1069 "R_MIPS_CALL_HI16", /* name */
1070 FALSE
, /* partial_inplace */
1072 0x0000ffff, /* dst_mask */
1073 FALSE
), /* pcrel_offset */
1075 /* Low 16 bits of displacement in global offset table. */
1076 HOWTO (R_MIPS_CALL_LO16
, /* type */
1078 2, /* size (0 = byte, 1 = short, 2 = long) */
1080 FALSE
, /* pc_relative */
1082 complain_overflow_dont
, /* complain_on_overflow */
1083 _bfd_mips_elf_generic_reloc
, /* special_function */
1084 "R_MIPS_CALL_LO16", /* name */
1085 FALSE
, /* partial_inplace */
1087 0x0000ffff, /* dst_mask */
1088 FALSE
), /* pcrel_offset */
1090 /* Section displacement, used by an associated event location section. */
1091 HOWTO (R_MIPS_SCN_DISP
, /* type */
1093 2, /* size (0 = byte, 1 = short, 2 = long) */
1095 FALSE
, /* pc_relative */
1097 complain_overflow_dont
, /* complain_on_overflow */
1098 _bfd_mips_elf_generic_reloc
, /* special_function */
1099 "R_MIPS_SCN_DISP", /* name */
1100 FALSE
, /* partial_inplace */
1102 0xffffffff, /* dst_mask */
1103 FALSE
), /* pcrel_offset */
1105 HOWTO (R_MIPS_REL16
, /* type */
1107 1, /* size (0 = byte, 1 = short, 2 = long) */
1109 FALSE
, /* pc_relative */
1111 complain_overflow_signed
, /* complain_on_overflow */
1112 _bfd_mips_elf_generic_reloc
, /* special_function */
1113 "R_MIPS_REL16", /* name */
1114 FALSE
, /* partial_inplace */
1116 0xffff, /* dst_mask */
1117 FALSE
), /* pcrel_offset */
1119 /* These two are obsolete. */
1120 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
1121 EMPTY_HOWTO (R_MIPS_PJUMP
),
1123 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1124 It must be used for multigot GOT's (and only there). */
1125 HOWTO (R_MIPS_RELGOT
, /* type */
1127 2, /* size (0 = byte, 1 = short, 2 = long) */
1129 FALSE
, /* pc_relative */
1131 complain_overflow_dont
, /* complain_on_overflow */
1132 _bfd_mips_elf_generic_reloc
, /* special_function */
1133 "R_MIPS_RELGOT", /* name */
1134 FALSE
, /* partial_inplace */
1136 0xffffffff, /* dst_mask */
1137 FALSE
), /* pcrel_offset */
1139 /* Protected jump conversion. This is an optimization hint. No
1140 relocation is required for correctness. */
1141 HOWTO (R_MIPS_JALR
, /* type */
1143 2, /* size (0 = byte, 1 = short, 2 = long) */
1145 FALSE
, /* pc_relative */
1147 complain_overflow_dont
, /* complain_on_overflow */
1148 _bfd_mips_elf_generic_reloc
, /* special_function */
1149 "R_MIPS_JALR", /* name */
1150 FALSE
, /* partial_inplace */
1152 0x00000000, /* dst_mask */
1153 FALSE
), /* pcrel_offset */
1156 static reloc_howto_type mips16_elf64_howto_table_rel
[] =
1158 /* The reloc used for the mips16 jump instruction. */
1159 HOWTO (R_MIPS16_26
, /* type */
1161 2, /* size (0 = byte, 1 = short, 2 = long) */
1163 FALSE
, /* pc_relative */
1165 complain_overflow_dont
, /* complain_on_overflow */
1166 /* This needs complex overflow
1167 detection, because the upper four
1168 bits must match the PC. */
1169 mips16_jump_reloc
, /* special_function */
1170 "R_MIPS16_26", /* name */
1171 TRUE
, /* partial_inplace */
1172 0x3ffffff, /* src_mask */
1173 0x3ffffff, /* dst_mask */
1174 FALSE
), /* pcrel_offset */
1176 /* The reloc used for the mips16 gprel instruction. */
1177 HOWTO (R_MIPS16_GPREL
, /* type */
1179 2, /* size (0 = byte, 1 = short, 2 = long) */
1181 FALSE
, /* pc_relative */
1183 complain_overflow_signed
, /* complain_on_overflow */
1184 mips16_gprel_reloc
, /* special_function */
1185 "R_MIPS16_GPREL", /* name */
1186 TRUE
, /* partial_inplace */
1187 0x0000ffff, /* src_mask */
1188 0x0000ffff, /* dst_mask */
1189 FALSE
), /* pcrel_offset */
1191 /* A placeholder for MIPS16 reference to global offset table. */
1192 EMPTY_HOWTO (R_MIPS16_GOT16
),
1194 /* A placeholder for MIPS16 16 bit call through global offset table. */
1195 EMPTY_HOWTO (R_MIPS16_CALL16
),
1197 /* MIPS16 high 16 bits of symbol value. */
1198 HOWTO (R_MIPS16_HI16
, /* type */
1199 16, /* rightshift */
1200 2, /* size (0 = byte, 1 = short, 2 = long) */
1202 FALSE
, /* pc_relative */
1204 complain_overflow_dont
, /* complain_on_overflow */
1205 _bfd_mips_elf_hi16_reloc
, /* special_function */
1206 "R_MIPS16_HI16", /* name */
1207 TRUE
, /* partial_inplace */
1208 0x0000ffff, /* src_mask */
1209 0x0000ffff, /* dst_mask */
1210 FALSE
), /* pcrel_offset */
1212 /* MIPS16 low 16 bits of symbol value. */
1213 HOWTO (R_MIPS16_LO16
, /* type */
1215 2, /* size (0 = byte, 1 = short, 2 = long) */
1217 FALSE
, /* pc_relative */
1219 complain_overflow_dont
, /* complain_on_overflow */
1220 _bfd_mips_elf_lo16_reloc
, /* special_function */
1221 "R_MIPS16_LO16", /* name */
1222 TRUE
, /* partial_inplace */
1223 0x0000ffff, /* src_mask */
1224 0x0000ffff, /* dst_mask */
1225 FALSE
), /* pcrel_offset */
1228 static reloc_howto_type mips16_elf64_howto_table_rela
[] =
1230 /* The reloc used for the mips16 jump instruction. */
1231 HOWTO (R_MIPS16_26
, /* type */
1233 2, /* size (0 = byte, 1 = short, 2 = long) */
1235 FALSE
, /* pc_relative */
1237 complain_overflow_dont
, /* complain_on_overflow */
1238 /* This needs complex overflow
1239 detection, because the upper four
1240 bits must match the PC. */
1241 mips16_jump_reloc
, /* special_function */
1242 "R_MIPS16_26", /* name */
1243 FALSE
, /* partial_inplace */
1244 0x3ffffff, /* src_mask */
1245 0x3ffffff, /* dst_mask */
1246 FALSE
), /* pcrel_offset */
1248 /* The reloc used for the mips16 gprel instruction. */
1249 HOWTO (R_MIPS16_GPREL
, /* type */
1251 2, /* size (0 = byte, 1 = short, 2 = long) */
1253 FALSE
, /* pc_relative */
1255 complain_overflow_signed
, /* complain_on_overflow */
1256 mips16_gprel_reloc
, /* special_function */
1257 "R_MIPS16_GPREL", /* name */
1258 FALSE
, /* partial_inplace */
1259 0x0000ffff, /* src_mask */
1260 0x0000ffff, /* dst_mask */
1261 FALSE
), /* pcrel_offset */
1263 /* A placeholder for MIPS16 reference to global offset table. */
1264 EMPTY_HOWTO (R_MIPS16_GOT16
),
1266 /* A placeholder for MIPS16 16 bit call through global offset table. */
1267 EMPTY_HOWTO (R_MIPS16_CALL16
),
1269 /* MIPS16 high 16 bits of symbol value. */
1270 HOWTO (R_MIPS16_HI16
, /* type */
1271 16, /* rightshift */
1272 2, /* size (0 = byte, 1 = short, 2 = long) */
1274 FALSE
, /* pc_relative */
1276 complain_overflow_dont
, /* complain_on_overflow */
1277 _bfd_mips_elf_hi16_reloc
, /* special_function */
1278 "R_MIPS16_HI16", /* name */
1279 FALSE
, /* partial_inplace */
1280 0x0000ffff, /* src_mask */
1281 0x0000ffff, /* dst_mask */
1282 FALSE
), /* pcrel_offset */
1284 /* MIPS16 low 16 bits of symbol value. */
1285 HOWTO (R_MIPS16_LO16
, /* type */
1287 2, /* size (0 = byte, 1 = short, 2 = long) */
1289 FALSE
, /* pc_relative */
1291 complain_overflow_dont
, /* complain_on_overflow */
1292 _bfd_mips_elf_lo16_reloc
, /* special_function */
1293 "R_MIPS16_LO16", /* name */
1294 FALSE
, /* partial_inplace */
1295 0x0000ffff, /* src_mask */
1296 0x0000ffff, /* dst_mask */
1297 FALSE
), /* pcrel_offset */
1300 /* GNU extension to record C++ vtable hierarchy */
1301 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
1302 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
1304 2, /* size (0 = byte, 1 = short, 2 = long) */
1306 FALSE
, /* pc_relative */
1308 complain_overflow_dont
, /* complain_on_overflow */
1309 NULL
, /* special_function */
1310 "R_MIPS_GNU_VTINHERIT", /* name */
1311 FALSE
, /* partial_inplace */
1314 FALSE
); /* pcrel_offset */
1316 /* GNU extension to record C++ vtable member usage */
1317 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
1318 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
1320 2, /* size (0 = byte, 1 = short, 2 = long) */
1322 FALSE
, /* pc_relative */
1324 complain_overflow_dont
, /* complain_on_overflow */
1325 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
1326 "R_MIPS_GNU_VTENTRY", /* name */
1327 FALSE
, /* partial_inplace */
1330 FALSE
); /* pcrel_offset */
1332 /* 16 bit offset for pc-relative branches. */
1333 static reloc_howto_type elf_mips_gnu_rel16_s2
=
1334 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1336 2, /* size (0 = byte, 1 = short, 2 = long) */
1338 TRUE
, /* pc_relative */
1340 complain_overflow_signed
, /* complain_on_overflow */
1341 _bfd_mips_elf_generic_reloc
, /* special_function */
1342 "R_MIPS_GNU_REL16_S2", /* name */
1343 TRUE
, /* partial_inplace */
1344 0x0000ffff, /* src_mask */
1345 0x0000ffff, /* dst_mask */
1346 TRUE
); /* pcrel_offset */
1348 /* 16 bit offset for pc-relative branches. */
1349 static reloc_howto_type elf_mips_gnu_rela16_s2
=
1350 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1352 2, /* size (0 = byte, 1 = short, 2 = long) */
1354 TRUE
, /* pc_relative */
1356 complain_overflow_signed
, /* complain_on_overflow */
1357 _bfd_mips_elf_generic_reloc
, /* special_function */
1358 "R_MIPS_GNU_REL16_S2", /* name */
1359 FALSE
, /* partial_inplace */
1361 0x0000ffff, /* dst_mask */
1362 TRUE
); /* pcrel_offset */
1364 /* Swap in a MIPS 64-bit Rel reloc. */
1367 mips_elf64_swap_reloc_in (bfd
*abfd
, const Elf64_Mips_External_Rel
*src
,
1368 Elf64_Mips_Internal_Rela
*dst
)
1370 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1371 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1372 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1373 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1374 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1375 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1379 /* Swap in a MIPS 64-bit Rela reloc. */
1382 mips_elf64_swap_reloca_in (bfd
*abfd
, const Elf64_Mips_External_Rela
*src
,
1383 Elf64_Mips_Internal_Rela
*dst
)
1385 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1386 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1387 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1388 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1389 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1390 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1391 dst
->r_addend
= H_GET_S64 (abfd
, src
->r_addend
);
1394 /* Swap out a MIPS 64-bit Rel reloc. */
1397 mips_elf64_swap_reloc_out (bfd
*abfd
, const Elf64_Mips_Internal_Rela
*src
,
1398 Elf64_Mips_External_Rel
*dst
)
1400 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1401 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1402 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1403 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1404 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1405 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1408 /* Swap out a MIPS 64-bit Rela reloc. */
1411 mips_elf64_swap_reloca_out (bfd
*abfd
, const Elf64_Mips_Internal_Rela
*src
,
1412 Elf64_Mips_External_Rela
*dst
)
1414 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1415 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1416 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1417 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1418 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1419 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1420 H_PUT_S64 (abfd
, src
->r_addend
, dst
->r_addend
);
1423 /* Swap in a MIPS 64-bit Rel reloc. */
1426 mips_elf64_be_swap_reloc_in (bfd
*abfd
, const bfd_byte
*src
,
1427 Elf_Internal_Rela
*dst
)
1429 Elf64_Mips_Internal_Rela mirel
;
1431 mips_elf64_swap_reloc_in (abfd
,
1432 (const Elf64_Mips_External_Rel
*) src
,
1435 dst
[0].r_offset
= mirel
.r_offset
;
1436 dst
[0].r_info
= ELF64_R_INFO (mirel
.r_sym
, mirel
.r_type
);
1437 dst
[0].r_addend
= 0;
1438 dst
[1].r_offset
= mirel
.r_offset
;
1439 dst
[1].r_info
= ELF64_R_INFO (mirel
.r_ssym
, mirel
.r_type2
);
1440 dst
[1].r_addend
= 0;
1441 dst
[2].r_offset
= mirel
.r_offset
;
1442 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirel
.r_type3
);
1443 dst
[2].r_addend
= 0;
1446 /* Swap in a MIPS 64-bit Rela reloc. */
1449 mips_elf64_be_swap_reloca_in (bfd
*abfd
, const bfd_byte
*src
,
1450 Elf_Internal_Rela
*dst
)
1452 Elf64_Mips_Internal_Rela mirela
;
1454 mips_elf64_swap_reloca_in (abfd
,
1455 (const Elf64_Mips_External_Rela
*) src
,
1458 dst
[0].r_offset
= mirela
.r_offset
;
1459 dst
[0].r_info
= ELF64_R_INFO (mirela
.r_sym
, mirela
.r_type
);
1460 dst
[0].r_addend
= mirela
.r_addend
;
1461 dst
[1].r_offset
= mirela
.r_offset
;
1462 dst
[1].r_info
= ELF64_R_INFO (mirela
.r_ssym
, mirela
.r_type2
);
1463 dst
[1].r_addend
= 0;
1464 dst
[2].r_offset
= mirela
.r_offset
;
1465 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirela
.r_type3
);
1466 dst
[2].r_addend
= 0;
1469 /* Swap out a MIPS 64-bit Rel reloc. */
1472 mips_elf64_be_swap_reloc_out (bfd
*abfd
, const Elf_Internal_Rela
*src
,
1475 Elf64_Mips_Internal_Rela mirel
;
1477 mirel
.r_offset
= src
[0].r_offset
;
1478 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1480 mirel
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1481 mirel
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1482 mirel
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1483 mirel
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1484 mirel
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1486 mips_elf64_swap_reloc_out (abfd
, &mirel
,
1487 (Elf64_Mips_External_Rel
*) dst
);
1490 /* Swap out a MIPS 64-bit Rela reloc. */
1493 mips_elf64_be_swap_reloca_out (bfd
*abfd
, const Elf_Internal_Rela
*src
,
1496 Elf64_Mips_Internal_Rela mirela
;
1498 mirela
.r_offset
= src
[0].r_offset
;
1499 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1500 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1502 mirela
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1503 mirela
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1504 mirela
.r_addend
= src
[0].r_addend
;
1505 BFD_ASSERT(src
[1].r_addend
== 0);
1506 BFD_ASSERT(src
[2].r_addend
== 0);
1508 mirela
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1509 mirela
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1510 mirela
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1512 mips_elf64_swap_reloca_out (abfd
, &mirela
,
1513 (Elf64_Mips_External_Rela
*) dst
);
1516 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1517 dangerous relocation. */
1520 mips_elf64_assign_gp (bfd
*output_bfd
, bfd_vma
*pgp
)
1526 /* If we've already figured out what GP will be, just return it. */
1527 *pgp
= _bfd_get_gp_value (output_bfd
);
1531 count
= bfd_get_symcount (output_bfd
);
1532 sym
= bfd_get_outsymbols (output_bfd
);
1534 /* The linker script will have created a symbol named `_gp' with the
1535 appropriate value. */
1540 for (i
= 0; i
< count
; i
++, sym
++)
1542 register const char *name
;
1544 name
= bfd_asymbol_name (*sym
);
1545 if (*name
== '_' && strcmp (name
, "_gp") == 0)
1547 *pgp
= bfd_asymbol_value (*sym
);
1548 _bfd_set_gp_value (output_bfd
, *pgp
);
1556 /* Only get the error once. */
1558 _bfd_set_gp_value (output_bfd
, *pgp
);
1565 /* We have to figure out the gp value, so that we can adjust the
1566 symbol value correctly. We look up the symbol _gp in the output
1567 BFD. If we can't find it, we're stuck. We cache it in the ELF
1568 target data. We don't need to adjust the symbol value for an
1569 external symbol if we are producing relocatable output. */
1571 static bfd_reloc_status_type
1572 mips_elf64_final_gp (bfd
*output_bfd
, asymbol
*symbol
, bfd_boolean relocatable
,
1573 char **error_message
, bfd_vma
*pgp
)
1575 if (bfd_is_und_section (symbol
->section
)
1579 return bfd_reloc_undefined
;
1582 *pgp
= _bfd_get_gp_value (output_bfd
);
1585 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
1589 /* Make up a value. */
1590 *pgp
= symbol
->section
->output_section
->vma
/*+ 0x4000*/;
1591 _bfd_set_gp_value (output_bfd
, *pgp
);
1593 else if (!mips_elf64_assign_gp (output_bfd
, pgp
))
1596 (char *) _("GP relative relocation when _gp not defined");
1597 return bfd_reloc_dangerous
;
1601 return bfd_reloc_ok
;
1604 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1605 become the offset from the gp register. */
1607 static bfd_reloc_status_type
1608 mips_elf64_gprel16_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1609 void *data
, asection
*input_section
, bfd
*output_bfd
,
1610 char **error_message
)
1612 bfd_boolean relocatable
;
1613 bfd_reloc_status_type ret
;
1616 /* If we're relocating, and this is an external symbol, we don't want
1617 to change anything. */
1618 if (output_bfd
!= NULL
1619 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1620 && (symbol
->flags
& BSF_LOCAL
) != 0)
1622 reloc_entry
->address
+= input_section
->output_offset
;
1623 return bfd_reloc_ok
;
1626 if (output_bfd
!= NULL
)
1630 relocatable
= FALSE
;
1631 output_bfd
= symbol
->section
->output_section
->owner
;
1634 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
1636 if (ret
!= bfd_reloc_ok
)
1639 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1640 input_section
, relocatable
,
1644 /* Do a R_MIPS_LITERAL relocation. */
1646 static bfd_reloc_status_type
1647 mips_elf64_literal_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1648 void *data
, asection
*input_section
, bfd
*output_bfd
,
1649 char **error_message
)
1651 bfd_boolean relocatable
;
1652 bfd_reloc_status_type ret
;
1655 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
1656 if (output_bfd
!= NULL
1657 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1658 && (symbol
->flags
& BSF_LOCAL
) != 0)
1660 *error_message
= (char *)
1661 _("literal relocation occurs for an external symbol");
1662 return bfd_reloc_outofrange
;
1665 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1666 if (output_bfd
!= NULL
)
1670 relocatable
= FALSE
;
1671 output_bfd
= symbol
->section
->output_section
->owner
;
1674 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
1676 if (ret
!= bfd_reloc_ok
)
1679 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1680 input_section
, relocatable
,
1684 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1685 become the offset from the gp register. */
1687 static bfd_reloc_status_type
1688 mips_elf64_gprel32_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1689 void *data
, asection
*input_section
, bfd
*output_bfd
,
1690 char **error_message
)
1692 bfd_boolean relocatable
;
1693 bfd_reloc_status_type ret
;
1698 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1699 if (output_bfd
!= NULL
1700 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1701 && (symbol
->flags
& BSF_LOCAL
) != 0)
1703 *error_message
= (char *)
1704 _("32bits gp relative relocation occurs for an external symbol");
1705 return bfd_reloc_outofrange
;
1708 if (output_bfd
!= NULL
)
1712 relocatable
= FALSE
;
1713 output_bfd
= symbol
->section
->output_section
->owner
;
1716 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
,
1717 error_message
, &gp
);
1718 if (ret
!= bfd_reloc_ok
)
1721 if (bfd_is_com_section (symbol
->section
))
1724 relocation
= symbol
->value
;
1726 relocation
+= symbol
->section
->output_section
->vma
;
1727 relocation
+= symbol
->section
->output_offset
;
1729 if (reloc_entry
->address
> bfd_get_section_limit (abfd
, input_section
))
1730 return bfd_reloc_outofrange
;
1732 /* Set val to the offset into the section or symbol. */
1733 val
= reloc_entry
->addend
;
1735 if (reloc_entry
->howto
->partial_inplace
)
1736 val
+= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1738 /* Adjust val for the final section location and GP value. If we
1739 are producing relocatable output, we don't want to do this for
1740 an external symbol. */
1742 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1743 val
+= relocation
- gp
;
1745 if (reloc_entry
->howto
->partial_inplace
)
1746 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
1748 reloc_entry
->addend
= val
;
1751 reloc_entry
->address
+= input_section
->output_offset
;
1753 return bfd_reloc_ok
;
1756 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1757 the rest is at bits 6-10. The bitpos already got right by the howto. */
1759 static bfd_reloc_status_type
1760 mips_elf64_shift6_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1761 void *data
, asection
*input_section
, bfd
*output_bfd
,
1762 char **error_message
)
1764 if (reloc_entry
->howto
->partial_inplace
)
1766 reloc_entry
->addend
= ((reloc_entry
->addend
& 0x00007c0)
1767 | (reloc_entry
->addend
& 0x00000800) >> 9);
1770 return _bfd_mips_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
1771 input_section
, output_bfd
,
1775 /* Handle a mips16 jump. */
1777 static bfd_reloc_status_type
1778 mips16_jump_reloc (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*reloc_entry
,
1779 asymbol
*symbol
, void *data ATTRIBUTE_UNUSED
,
1780 asection
*input_section
, bfd
*output_bfd
,
1781 char **error_message ATTRIBUTE_UNUSED
)
1783 if (output_bfd
!= NULL
1784 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1785 && (! reloc_entry
->howto
->partial_inplace
1786 || reloc_entry
->addend
== 0))
1788 reloc_entry
->address
+= input_section
->output_offset
;
1789 return bfd_reloc_ok
;
1794 static bfd_boolean warned
;
1797 (*_bfd_error_handler
)
1798 (_("Linking mips16 objects into %s format is not supported"),
1799 bfd_get_target (input_section
->output_section
->owner
));
1803 return bfd_reloc_undefined
;
1806 /* Handle a mips16 GP relative reloc. */
1808 static bfd_reloc_status_type
1809 mips16_gprel_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1810 void *data
, asection
*input_section
, bfd
*output_bfd
,
1811 char **error_message
)
1813 bfd_boolean relocatable
;
1814 bfd_reloc_status_type ret
;
1818 /* If we're relocating, and this is an external symbol, we don't want
1819 to change anything. */
1820 if (output_bfd
!= NULL
1821 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1822 && (symbol
->flags
& BSF_LOCAL
) != 0)
1824 reloc_entry
->address
+= input_section
->output_offset
;
1825 return bfd_reloc_ok
;
1828 if (output_bfd
!= NULL
)
1832 relocatable
= FALSE
;
1833 output_bfd
= symbol
->section
->output_section
->owner
;
1836 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
1838 if (ret
!= bfd_reloc_ok
)
1841 location
= (bfd_byte
*) data
+ reloc_entry
->address
;
1842 _bfd_mips16_elf_reloc_unshuffle (abfd
, reloc_entry
->howto
->type
, FALSE
,
1844 ret
= _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1845 input_section
, relocatable
,
1847 _bfd_mips16_elf_reloc_shuffle (abfd
, reloc_entry
->howto
->type
, !relocatable
,
1853 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1855 struct elf_reloc_map
{
1856 bfd_reloc_code_real_type bfd_val
;
1857 enum elf_mips_reloc_type elf_val
;
1860 static const struct elf_reloc_map mips_reloc_map
[] =
1862 { BFD_RELOC_NONE
, R_MIPS_NONE
},
1863 { BFD_RELOC_16
, R_MIPS_16
},
1864 { BFD_RELOC_32
, R_MIPS_32
},
1865 /* There is no BFD reloc for R_MIPS_REL32. */
1866 { BFD_RELOC_64
, R_MIPS_64
},
1867 { BFD_RELOC_CTOR
, R_MIPS_64
},
1868 { BFD_RELOC_16_PCREL
, R_MIPS_PC16
},
1869 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
1870 { BFD_RELOC_LO16
, R_MIPS_LO16
},
1871 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
1872 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
1873 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
1874 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
1875 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
1876 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
1877 { BFD_RELOC_MIPS_SHIFT5
, R_MIPS_SHIFT5
},
1878 { BFD_RELOC_MIPS_SHIFT6
, R_MIPS_SHIFT6
},
1879 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
},
1880 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
1881 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
1882 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
1883 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
1884 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
1885 { BFD_RELOC_MIPS_INSERT_A
, R_MIPS_INSERT_A
},
1886 { BFD_RELOC_MIPS_INSERT_B
, R_MIPS_INSERT_B
},
1887 { BFD_RELOC_MIPS_DELETE
, R_MIPS_DELETE
},
1888 { BFD_RELOC_MIPS_HIGHEST
, R_MIPS_HIGHEST
},
1889 { BFD_RELOC_MIPS_HIGHER
, R_MIPS_HIGHER
},
1890 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
1891 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
1892 { BFD_RELOC_MIPS_SCN_DISP
, R_MIPS_SCN_DISP
},
1893 { BFD_RELOC_MIPS_REL16
, R_MIPS_REL16
},
1894 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1895 { BFD_RELOC_MIPS_RELGOT
, R_MIPS_RELGOT
},
1896 { BFD_RELOC_MIPS_JALR
, R_MIPS_JALR
}
1899 static const struct elf_reloc_map mips16_reloc_map
[] =
1901 { BFD_RELOC_MIPS16_JMP
, R_MIPS16_26
- R_MIPS16_min
},
1902 { BFD_RELOC_MIPS16_GPREL
, R_MIPS16_GPREL
- R_MIPS16_min
},
1903 { BFD_RELOC_MIPS16_HI16_S
, R_MIPS16_HI16
- R_MIPS16_min
},
1904 { BFD_RELOC_MIPS16_LO16
, R_MIPS16_LO16
- R_MIPS16_min
},
1907 /* Given a BFD reloc type, return a howto structure. */
1909 static reloc_howto_type
*
1910 bfd_elf64_bfd_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1911 bfd_reloc_code_real_type code
)
1914 /* FIXME: We default to RELA here instead of choosing the right
1915 relocation variant. */
1916 reloc_howto_type
*howto_table
= mips_elf64_howto_table_rela
;
1917 reloc_howto_type
*howto16_table
= mips16_elf64_howto_table_rela
;
1919 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
1922 if (mips_reloc_map
[i
].bfd_val
== code
)
1923 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
1926 for (i
= 0; i
< sizeof (mips16_reloc_map
) / sizeof (struct elf_reloc_map
);
1929 if (mips16_reloc_map
[i
].bfd_val
== code
)
1930 return &howto16_table
[(int) mips16_reloc_map
[i
].elf_val
];
1935 case BFD_RELOC_VTABLE_INHERIT
:
1936 return &elf_mips_gnu_vtinherit_howto
;
1937 case BFD_RELOC_VTABLE_ENTRY
:
1938 return &elf_mips_gnu_vtentry_howto
;
1939 case BFD_RELOC_16_PCREL_S2
:
1940 return &elf_mips_gnu_rela16_s2
;
1942 bfd_set_error (bfd_error_bad_value
);
1947 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1949 static reloc_howto_type
*
1950 mips_elf64_rtype_to_howto (unsigned int r_type
, bfd_boolean rela_p
)
1954 case R_MIPS_GNU_VTINHERIT
:
1955 return &elf_mips_gnu_vtinherit_howto
;
1956 case R_MIPS_GNU_VTENTRY
:
1957 return &elf_mips_gnu_vtentry_howto
;
1958 case R_MIPS_GNU_REL16_S2
:
1960 return &elf_mips_gnu_rela16_s2
;
1962 return &elf_mips_gnu_rel16_s2
;
1964 if (r_type
>= R_MIPS16_min
&& r_type
< R_MIPS16_max
)
1967 return &mips16_elf64_howto_table_rela
[r_type
- R_MIPS16_min
];
1969 return &mips16_elf64_howto_table_rel
[r_type
- R_MIPS16_min
];
1971 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
1973 return &mips_elf64_howto_table_rela
[r_type
];
1975 return &mips_elf64_howto_table_rel
[r_type
];
1980 /* Prevent relocation handling by bfd for MIPS ELF64. */
1983 mips_elf64_info_to_howto_rel (bfd
*abfd ATTRIBUTE_UNUSED
,
1984 arelent
*cache_ptr ATTRIBUTE_UNUSED
,
1985 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
)
1991 mips_elf64_info_to_howto_rela (bfd
*abfd ATTRIBUTE_UNUSED
,
1992 arelent
*cache_ptr ATTRIBUTE_UNUSED
,
1993 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
)
1998 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
1999 to three relocs, we must tell the user to allocate more space. */
2002 mips_elf64_get_reloc_upper_bound (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
)
2004 return (sec
->reloc_count
* 3 + 1) * sizeof (arelent
*);
2008 mips_elf64_get_dynamic_reloc_upper_bound (bfd
*abfd
)
2010 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd
) * 3;
2013 /* We must also copy more relocations than the corresponding functions
2014 in elf.c would, so the two following functions are slightly
2015 modified from elf.c, that multiply the external relocation count by
2016 3 to obtain the internal relocation count. */
2019 mips_elf64_canonicalize_reloc (bfd
*abfd
, sec_ptr section
,
2020 arelent
**relptr
, asymbol
**symbols
)
2024 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
2026 if (! bed
->s
->slurp_reloc_table (abfd
, section
, symbols
, FALSE
))
2029 tblptr
= section
->relocation
;
2030 for (i
= 0; i
< section
->reloc_count
* 3; i
++)
2031 *relptr
++ = tblptr
++;
2035 return section
->reloc_count
* 3;
2039 mips_elf64_canonicalize_dynamic_reloc (bfd
*abfd
, arelent
**storage
,
2042 bfd_boolean (*slurp_relocs
) (bfd
*, asection
*, asymbol
**, bfd_boolean
);
2046 if (elf_dynsymtab (abfd
) == 0)
2048 bfd_set_error (bfd_error_invalid_operation
);
2052 slurp_relocs
= get_elf_backend_data (abfd
)->s
->slurp_reloc_table
;
2054 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
2056 if (elf_section_data (s
)->this_hdr
.sh_link
== elf_dynsymtab (abfd
)
2057 && (elf_section_data (s
)->this_hdr
.sh_type
== SHT_REL
2058 || elf_section_data (s
)->this_hdr
.sh_type
== SHT_RELA
))
2063 if (! (*slurp_relocs
) (abfd
, s
, syms
, TRUE
))
2065 count
= s
->size
/ elf_section_data (s
)->this_hdr
.sh_entsize
* 3;
2067 for (i
= 0; i
< count
; i
++)
2078 /* Read the relocations from one reloc section. This is mostly copied
2079 from elfcode.h, except for the changes to expand one external
2080 relocation to 3 internal ones. We must unfortunately set
2081 reloc_count to the number of external relocations, because a lot of
2082 generic code seems to depend on this. */
2085 mips_elf64_slurp_one_reloc_table (bfd
*abfd
, asection
*asect
,
2086 Elf_Internal_Shdr
*rel_hdr
,
2087 bfd_size_type reloc_count
,
2088 arelent
*relents
, asymbol
**symbols
,
2089 bfd_boolean dynamic
)
2092 bfd_byte
*native_relocs
;
2098 allocated
= bfd_malloc (rel_hdr
->sh_size
);
2099 if (allocated
== NULL
)
2102 if (bfd_seek (abfd
, rel_hdr
->sh_offset
, SEEK_SET
) != 0
2103 || (bfd_bread (allocated
, rel_hdr
->sh_size
, abfd
)
2104 != rel_hdr
->sh_size
))
2107 native_relocs
= allocated
;
2109 entsize
= rel_hdr
->sh_entsize
;
2110 BFD_ASSERT (entsize
== sizeof (Elf64_Mips_External_Rel
)
2111 || entsize
== sizeof (Elf64_Mips_External_Rela
));
2113 if (entsize
== sizeof (Elf64_Mips_External_Rel
))
2118 for (i
= 0, relent
= relents
;
2120 i
++, native_relocs
+= entsize
)
2122 Elf64_Mips_Internal_Rela rela
;
2123 bfd_boolean used_sym
, used_ssym
;
2126 if (entsize
== sizeof (Elf64_Mips_External_Rela
))
2127 mips_elf64_swap_reloca_in (abfd
,
2128 (Elf64_Mips_External_Rela
*) native_relocs
,
2131 mips_elf64_swap_reloc_in (abfd
,
2132 (Elf64_Mips_External_Rel
*) native_relocs
,
2135 /* Each entry represents exactly three actual relocations. */
2139 for (ir
= 0; ir
< 3; ir
++)
2141 enum elf_mips_reloc_type type
;
2148 type
= (enum elf_mips_reloc_type
) rela
.r_type
;
2151 type
= (enum elf_mips_reloc_type
) rela
.r_type2
;
2154 type
= (enum elf_mips_reloc_type
) rela
.r_type3
;
2158 /* Some types require symbols, whereas some do not. */
2162 case R_MIPS_LITERAL
:
2163 case R_MIPS_INSERT_A
:
2164 case R_MIPS_INSERT_B
:
2166 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2172 if (rela
.r_sym
== 0)
2173 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2178 ps
= symbols
+ rela
.r_sym
- 1;
2180 if ((s
->flags
& BSF_SECTION_SYM
) == 0)
2181 relent
->sym_ptr_ptr
= ps
;
2183 relent
->sym_ptr_ptr
= s
->section
->symbol_ptr_ptr
;
2188 else if (! used_ssym
)
2190 switch (rela
.r_ssym
)
2193 relent
->sym_ptr_ptr
=
2194 bfd_abs_section_ptr
->symbol_ptr_ptr
;
2200 /* FIXME: I think these need to be handled using
2201 special howto structures. */
2213 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2218 /* The address of an ELF reloc is section relative for an
2219 object file, and absolute for an executable file or
2220 shared library. The address of a BFD reloc is always
2221 section relative. */
2222 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0 || dynamic
)
2223 relent
->address
= rela
.r_offset
;
2225 relent
->address
= rela
.r_offset
- asect
->vma
;
2227 relent
->addend
= rela
.r_addend
;
2229 relent
->howto
= mips_elf64_rtype_to_howto (type
, rela_p
);
2235 asect
->reloc_count
+= (relent
- relents
) / 3;
2237 if (allocated
!= NULL
)
2243 if (allocated
!= NULL
)
2248 /* Read the relocations. On Irix 6, there can be two reloc sections
2249 associated with a single data section. This is copied from
2250 elfcode.h as well, with changes as small as accounting for 3
2251 internal relocs per external reloc and resetting reloc_count to
2252 zero before processing the relocs of a section. */
2255 mips_elf64_slurp_reloc_table (bfd
*abfd
, asection
*asect
,
2256 asymbol
**symbols
, bfd_boolean dynamic
)
2258 struct bfd_elf_section_data
* const d
= elf_section_data (asect
);
2259 Elf_Internal_Shdr
*rel_hdr
;
2260 Elf_Internal_Shdr
*rel_hdr2
;
2261 bfd_size_type reloc_count
;
2262 bfd_size_type reloc_count2
;
2266 if (asect
->relocation
!= NULL
)
2271 if ((asect
->flags
& SEC_RELOC
) == 0
2272 || asect
->reloc_count
== 0)
2275 rel_hdr
= &d
->rel_hdr
;
2276 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2277 rel_hdr2
= d
->rel_hdr2
;
2278 reloc_count2
= (rel_hdr2
? NUM_SHDR_ENTRIES (rel_hdr2
) : 0);
2280 BFD_ASSERT (asect
->reloc_count
== reloc_count
+ reloc_count2
);
2281 BFD_ASSERT (asect
->rel_filepos
== rel_hdr
->sh_offset
2282 || (rel_hdr2
&& asect
->rel_filepos
== rel_hdr2
->sh_offset
));
2287 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2288 case because relocations against this section may use the
2289 dynamic symbol table, and in that case bfd_section_from_shdr
2290 in elf.c does not update the RELOC_COUNT. */
2291 if (asect
->size
== 0)
2294 rel_hdr
= &d
->this_hdr
;
2295 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2300 /* Allocate space for 3 arelent structures for each Rel structure. */
2301 amt
= (reloc_count
+ reloc_count2
) * 3 * sizeof (arelent
);
2302 relents
= bfd_alloc (abfd
, amt
);
2303 if (relents
== NULL
)
2306 /* The slurp_one_reloc_table routine increments reloc_count. */
2307 asect
->reloc_count
= 0;
2309 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2310 rel_hdr
, reloc_count
,
2314 if (d
->rel_hdr2
!= NULL
)
2316 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2317 rel_hdr2
, reloc_count2
,
2318 relents
+ reloc_count
* 3,
2323 asect
->relocation
= relents
;
2327 /* Write out the relocations. */
2330 mips_elf64_write_relocs (bfd
*abfd
, asection
*sec
, void *data
)
2332 bfd_boolean
*failedp
= data
;
2334 Elf_Internal_Shdr
*rel_hdr
;
2337 /* If we have already failed, don't do anything. */
2341 if ((sec
->flags
& SEC_RELOC
) == 0)
2344 /* The linker backend writes the relocs out itself, and sets the
2345 reloc_count field to zero to inhibit writing them here. Also,
2346 sometimes the SEC_RELOC flag gets set even when there aren't any
2348 if (sec
->reloc_count
== 0)
2351 /* We can combine up to three relocs that refer to the same address
2352 if the latter relocs have no associated symbol. */
2354 for (idx
= 0; idx
< sec
->reloc_count
; idx
++)
2361 addr
= sec
->orelocation
[idx
]->address
;
2362 for (i
= 0; i
< 2; i
++)
2366 if (idx
+ 1 >= sec
->reloc_count
)
2368 r
= sec
->orelocation
[idx
+ 1];
2369 if (r
->address
!= addr
2370 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2371 || (*r
->sym_ptr_ptr
)->value
!= 0)
2374 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2380 rel_hdr
= &elf_section_data (sec
)->rel_hdr
;
2382 /* Do the actual relocation. */
2384 if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rel
))
2385 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, &count
, data
);
2386 else if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rela
))
2387 mips_elf64_write_rela (abfd
, sec
, rel_hdr
, &count
, data
);
2393 mips_elf64_write_rel (bfd
*abfd
, asection
*sec
,
2394 Elf_Internal_Shdr
*rel_hdr
,
2395 int *count
, void *data
)
2397 bfd_boolean
*failedp
= data
;
2398 Elf64_Mips_External_Rel
*ext_rel
;
2400 asymbol
*last_sym
= 0;
2401 int last_sym_idx
= 0;
2403 rel_hdr
->sh_size
= rel_hdr
->sh_entsize
* *count
;
2404 rel_hdr
->contents
= bfd_alloc (abfd
, rel_hdr
->sh_size
);
2405 if (rel_hdr
->contents
== NULL
)
2411 ext_rel
= (Elf64_Mips_External_Rel
*) rel_hdr
->contents
;
2412 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rel
++)
2415 Elf64_Mips_Internal_Rela int_rel
;
2420 ptr
= sec
->orelocation
[idx
];
2422 /* The address of an ELF reloc is section relative for an object
2423 file, and absolute for an executable file or shared library.
2424 The address of a BFD reloc is always section relative. */
2425 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2426 int_rel
.r_offset
= ptr
->address
;
2428 int_rel
.r_offset
= ptr
->address
+ sec
->vma
;
2430 sym
= *ptr
->sym_ptr_ptr
;
2431 if (sym
== last_sym
)
2433 else if (bfd_is_abs_section (sym
->section
) && sym
->value
== 0)
2438 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2448 int_rel
.r_ssym
= RSS_UNDEF
;
2450 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2451 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2457 int_rel
.r_type
= ptr
->howto
->type
;
2458 int_rel
.r_type2
= (int) R_MIPS_NONE
;
2459 int_rel
.r_type3
= (int) R_MIPS_NONE
;
2461 for (i
= 0; i
< 2; i
++)
2465 if (idx
+ 1 >= sec
->reloc_count
)
2467 r
= sec
->orelocation
[idx
+ 1];
2468 if (r
->address
!= ptr
->address
2469 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2470 || (*r
->sym_ptr_ptr
)->value
!= 0)
2473 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2476 int_rel
.r_type2
= r
->howto
->type
;
2478 int_rel
.r_type3
= r
->howto
->type
;
2483 mips_elf64_swap_reloc_out (abfd
, &int_rel
, ext_rel
);
2486 BFD_ASSERT (ext_rel
- (Elf64_Mips_External_Rel
*) rel_hdr
->contents
2491 mips_elf64_write_rela (bfd
*abfd
, asection
*sec
,
2492 Elf_Internal_Shdr
*rela_hdr
,
2493 int *count
, void *data
)
2495 bfd_boolean
*failedp
= data
;
2496 Elf64_Mips_External_Rela
*ext_rela
;
2498 asymbol
*last_sym
= 0;
2499 int last_sym_idx
= 0;
2501 rela_hdr
->sh_size
= rela_hdr
->sh_entsize
* *count
;
2502 rela_hdr
->contents
= bfd_alloc (abfd
, rela_hdr
->sh_size
);
2503 if (rela_hdr
->contents
== NULL
)
2509 ext_rela
= (Elf64_Mips_External_Rela
*) rela_hdr
->contents
;
2510 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rela
++)
2513 Elf64_Mips_Internal_Rela int_rela
;
2518 ptr
= sec
->orelocation
[idx
];
2520 /* The address of an ELF reloc is section relative for an object
2521 file, and absolute for an executable file or shared library.
2522 The address of a BFD reloc is always section relative. */
2523 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2524 int_rela
.r_offset
= ptr
->address
;
2526 int_rela
.r_offset
= ptr
->address
+ sec
->vma
;
2528 sym
= *ptr
->sym_ptr_ptr
;
2529 if (sym
== last_sym
)
2531 else if (bfd_is_abs_section (sym
->section
) && sym
->value
== 0)
2536 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2546 int_rela
.r_addend
= ptr
->addend
;
2547 int_rela
.r_ssym
= RSS_UNDEF
;
2549 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2550 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2556 int_rela
.r_type
= ptr
->howto
->type
;
2557 int_rela
.r_type2
= (int) R_MIPS_NONE
;
2558 int_rela
.r_type3
= (int) R_MIPS_NONE
;
2560 for (i
= 0; i
< 2; i
++)
2564 if (idx
+ 1 >= sec
->reloc_count
)
2566 r
= sec
->orelocation
[idx
+ 1];
2567 if (r
->address
!= ptr
->address
2568 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2569 || (*r
->sym_ptr_ptr
)->value
!= 0)
2572 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2575 int_rela
.r_type2
= r
->howto
->type
;
2577 int_rela
.r_type3
= r
->howto
->type
;
2582 mips_elf64_swap_reloca_out (abfd
, &int_rela
, ext_rela
);
2585 BFD_ASSERT (ext_rela
- (Elf64_Mips_External_Rela
*) rela_hdr
->contents
2589 /* Set the right machine number for a MIPS ELF file. */
2592 mips_elf64_object_p (bfd
*abfd
)
2596 /* Irix 6 is broken. Object file symbol tables are not always
2597 sorted correctly such that local symbols precede global symbols,
2598 and the sh_info field in the symbol table is not always right. */
2599 if (elf64_mips_irix_compat (abfd
) != ict_none
)
2600 elf_bad_symtab (abfd
) = TRUE
;
2602 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
2603 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
2607 /* Depending on the target vector we generate some version of Irix
2608 executables or "normal" MIPS ELF ABI executables. */
2609 static irix_compat_t
2610 elf64_mips_irix_compat (bfd
*abfd
)
2612 if ((abfd
->xvec
== &bfd_elf64_bigmips_vec
)
2613 || (abfd
->xvec
== &bfd_elf64_littlemips_vec
))
2619 /* Support for core dump NOTE sections. */
2621 elf64_mips_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
2626 switch (note
->descsz
)
2631 case 480: /* Linux/MIPS - N64 kernel */
2633 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
2636 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 32);
2645 /* Make a ".reg/999" section. */
2646 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
2647 size
, note
->descpos
+ offset
);
2651 elf64_mips_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
2653 switch (note
->descsz
)
2658 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2659 elf_tdata (abfd
)->core_program
2660 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
2661 elf_tdata (abfd
)->core_command
2662 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
2665 /* Note that for some reason, a spurious space is tacked
2666 onto the end of the args in some (at least one anyway)
2667 implementations, so strip it off if it exists. */
2670 char *command
= elf_tdata (abfd
)->core_command
;
2671 int n
= strlen (command
);
2673 if (0 < n
&& command
[n
- 1] == ' ')
2674 command
[n
- 1] = '\0';
2680 /* ECOFF swapping routines. These are used when dealing with the
2681 .mdebug section, which is in the ECOFF debugging format. */
2682 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap
=
2684 /* Symbol table magic number. */
2686 /* Alignment of debugging information. E.g., 4. */
2688 /* Sizes of external symbolic information. */
2689 sizeof (struct hdr_ext
),
2690 sizeof (struct dnr_ext
),
2691 sizeof (struct pdr_ext
),
2692 sizeof (struct sym_ext
),
2693 sizeof (struct opt_ext
),
2694 sizeof (struct fdr_ext
),
2695 sizeof (struct rfd_ext
),
2696 sizeof (struct ext_ext
),
2697 /* Functions to swap in external symbolic data. */
2706 _bfd_ecoff_swap_tir_in
,
2707 _bfd_ecoff_swap_rndx_in
,
2708 /* Functions to swap out external symbolic data. */
2717 _bfd_ecoff_swap_tir_out
,
2718 _bfd_ecoff_swap_rndx_out
,
2719 /* Function to read in symbolic data. */
2720 _bfd_mips_elf_read_ecoff_info
2723 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2724 standard ELF. This structure is used to redirect the relocation
2725 handling routines. */
2727 const struct elf_size_info mips_elf64_size_info
=
2729 sizeof (Elf64_External_Ehdr
),
2730 sizeof (Elf64_External_Phdr
),
2731 sizeof (Elf64_External_Shdr
),
2732 sizeof (Elf64_Mips_External_Rel
),
2733 sizeof (Elf64_Mips_External_Rela
),
2734 sizeof (Elf64_External_Sym
),
2735 sizeof (Elf64_External_Dyn
),
2736 sizeof (Elf_External_Note
),
2737 4, /* hash-table entry size */
2738 3, /* internal relocations per external relocations */
2740 3, /* log_file_align */
2743 bfd_elf64_write_out_phdrs
,
2744 bfd_elf64_write_shdrs_and_ehdr
,
2745 mips_elf64_write_relocs
,
2746 bfd_elf64_swap_symbol_in
,
2747 bfd_elf64_swap_symbol_out
,
2748 mips_elf64_slurp_reloc_table
,
2749 bfd_elf64_slurp_symbol_table
,
2750 bfd_elf64_swap_dyn_in
,
2751 bfd_elf64_swap_dyn_out
,
2752 mips_elf64_be_swap_reloc_in
,
2753 mips_elf64_be_swap_reloc_out
,
2754 mips_elf64_be_swap_reloca_in
,
2755 mips_elf64_be_swap_reloca_out
2758 #define ELF_ARCH bfd_arch_mips
2759 #define ELF_MACHINE_CODE EM_MIPS
2761 #define elf_backend_collect TRUE
2762 #define elf_backend_type_change_ok TRUE
2763 #define elf_backend_can_gc_sections TRUE
2764 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2765 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2766 #define elf_backend_object_p mips_elf64_object_p
2767 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2768 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2769 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2770 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2771 #define elf_backend_section_from_bfd_section \
2772 _bfd_mips_elf_section_from_bfd_section
2773 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2774 #define elf_backend_link_output_symbol_hook \
2775 _bfd_mips_elf_link_output_symbol_hook
2776 #define elf_backend_create_dynamic_sections \
2777 _bfd_mips_elf_create_dynamic_sections
2778 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2779 #define elf_backend_adjust_dynamic_symbol \
2780 _bfd_mips_elf_adjust_dynamic_symbol
2781 #define elf_backend_always_size_sections \
2782 _bfd_mips_elf_always_size_sections
2783 #define elf_backend_size_dynamic_sections \
2784 _bfd_mips_elf_size_dynamic_sections
2785 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2786 #define elf_backend_finish_dynamic_symbol \
2787 _bfd_mips_elf_finish_dynamic_symbol
2788 #define elf_backend_finish_dynamic_sections \
2789 _bfd_mips_elf_finish_dynamic_sections
2790 #define elf_backend_final_write_processing \
2791 _bfd_mips_elf_final_write_processing
2792 #define elf_backend_additional_program_headers \
2793 _bfd_mips_elf_additional_program_headers
2794 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2795 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2796 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2797 #define elf_backend_copy_indirect_symbol \
2798 _bfd_mips_elf_copy_indirect_symbol
2799 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2800 #define elf_backend_ignore_discarded_relocs \
2801 _bfd_mips_elf_ignore_discarded_relocs
2802 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2803 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2804 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2805 #define elf_backend_size_info mips_elf64_size_info
2807 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
2808 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
2810 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2812 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2813 work better/work only in RELA, so we default to this. */
2814 #define elf_backend_may_use_rel_p 1
2815 #define elf_backend_may_use_rela_p 1
2816 #define elf_backend_default_use_rela_p 1
2818 #define elf_backend_write_section _bfd_mips_elf_write_section
2820 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2821 MIPS-specific function only applies to IRIX5, which had no 64-bit
2823 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2824 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
2825 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2826 #define bfd_elf64_bfd_get_relocated_section_contents \
2827 _bfd_elf_mips_get_relocated_section_contents
2828 #define bfd_elf64_bfd_link_hash_table_create \
2829 _bfd_mips_elf_link_hash_table_create
2830 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2831 #define bfd_elf64_bfd_merge_private_bfd_data \
2832 _bfd_mips_elf_merge_private_bfd_data
2833 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2834 #define bfd_elf64_bfd_print_private_bfd_data \
2835 _bfd_mips_elf_print_private_bfd_data
2837 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2838 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
2839 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
2840 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
2841 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
2843 /* MIPS ELF64 archive functions. */
2844 #define bfd_elf64_archive_functions
2845 extern bfd_boolean bfd_elf64_archive_slurp_armap
2847 extern bfd_boolean bfd_elf64_archive_write_armap
2848 (bfd
*, unsigned int, struct orl
*, unsigned int, int);
2849 #define bfd_elf64_archive_slurp_extended_name_table \
2850 _bfd_archive_coff_slurp_extended_name_table
2851 #define bfd_elf64_archive_construct_extended_name_table \
2852 _bfd_archive_coff_construct_extended_name_table
2853 #define bfd_elf64_archive_truncate_arname \
2854 _bfd_archive_coff_truncate_arname
2855 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2856 #define bfd_elf64_archive_openr_next_archived_file \
2857 _bfd_archive_coff_openr_next_archived_file
2858 #define bfd_elf64_archive_get_elt_at_index \
2859 _bfd_archive_coff_get_elt_at_index
2860 #define bfd_elf64_archive_generic_stat_arch_elt \
2861 _bfd_archive_coff_generic_stat_arch_elt
2862 #define bfd_elf64_archive_update_armap_timestamp \
2863 _bfd_archive_coff_update_armap_timestamp
2865 /* The SGI style (n)64 NewABI. */
2866 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2867 #define TARGET_LITTLE_NAME "elf64-littlemips"
2868 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2869 #define TARGET_BIG_NAME "elf64-bigmips"
2871 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2872 a value of 0x1000, and we are compatible.
2873 FIXME: How does this affect NewABI? */
2874 #define ELF_MAXPAGESIZE 0x1000
2876 #include "elf64-target.h"
2878 /* The SYSV-style 'traditional' (n)64 NewABI. */
2879 #undef TARGET_LITTLE_SYM
2880 #undef TARGET_LITTLE_NAME
2881 #undef TARGET_BIG_SYM
2882 #undef TARGET_BIG_NAME
2884 #undef ELF_MAXPAGESIZE
2886 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2887 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2888 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2889 #define TARGET_BIG_NAME "elf64-tradbigmips"
2891 /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
2892 page sizes of up to that limit, so we need to respect it. */
2893 #define ELF_MAXPAGESIZE 0x10000
2894 #define elf64_bed elf64_tradbed
2896 /* Include the target file again for this target. */
2897 #include "elf64-target.h"