1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Ian Lance Taylor, Cygnus Support
6 Linker support added by Mark Mitchell, CodeSourcery, LLC.
7 <mark@codesourcery.com>
9 This file is part of BFD, the Binary File Descriptor library.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24 MA 02110-1301, USA. */
27 /* This file supports the 64-bit MIPS ELF ABI.
29 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
30 overrides the usual ELF reloc handling, and handles reading and
31 writing the relocations here. */
33 /* TODO: Many things are unsupported, even if there is some code for it
34 . (which was mostly stolen from elf32-mips.c and slightly adapted).
36 . - Relocation handling for REL relocs is wrong in many cases and
38 . - Relocation handling for RELA relocs related to GOT support are
39 . also likely to be wrong.
40 . - Support for MIPS16 is untested.
41 . - Combined relocs with RSS_* entries are unsupported.
42 . - The whole GOT handling for NewABI is missing, some parts of
43 . the OldABI version is still lying around and should be removed.
53 #include "elfxx-mips.h"
56 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
57 use ECOFF. However, we support it anyhow for an easier changeover. */
59 #include "coff/symconst.h"
60 #include "coff/internal.h"
61 #include "coff/ecoff.h"
62 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
63 #include "coff/alpha.h"
64 #define ECOFF_SIGNED_64
65 #include "ecoffswap.h"
67 static void mips_elf64_swap_reloc_in
68 (bfd
*, const Elf64_Mips_External_Rel
*, Elf64_Mips_Internal_Rela
*);
69 static void mips_elf64_swap_reloca_in
70 (bfd
*, const Elf64_Mips_External_Rela
*, Elf64_Mips_Internal_Rela
*);
71 static void mips_elf64_swap_reloc_out
72 (bfd
*, const Elf64_Mips_Internal_Rela
*, Elf64_Mips_External_Rel
*);
73 static void mips_elf64_swap_reloca_out
74 (bfd
*, const Elf64_Mips_Internal_Rela
*, Elf64_Mips_External_Rela
*);
75 static void mips_elf64_be_swap_reloc_in
76 (bfd
*, const bfd_byte
*, Elf_Internal_Rela
*);
77 static void mips_elf64_be_swap_reloc_out
78 (bfd
*, const Elf_Internal_Rela
*, bfd_byte
*);
79 static void mips_elf64_be_swap_reloca_in
80 (bfd
*, const bfd_byte
*, Elf_Internal_Rela
*);
81 static void mips_elf64_be_swap_reloca_out
82 (bfd
*, const Elf_Internal_Rela
*, bfd_byte
*);
83 static reloc_howto_type
*bfd_elf64_bfd_reloc_type_lookup
84 (bfd
*, bfd_reloc_code_real_type
);
85 static reloc_howto_type
*mips_elf64_rtype_to_howto
86 (unsigned int, bfd_boolean
);
87 static void mips_elf64_info_to_howto_rel
88 (bfd
*, arelent
*, Elf_Internal_Rela
*);
89 static void mips_elf64_info_to_howto_rela
90 (bfd
*, arelent
*, Elf_Internal_Rela
*);
91 static long mips_elf64_get_reloc_upper_bound
93 static long mips_elf64_canonicalize_reloc
94 (bfd
*, asection
*, arelent
**, asymbol
**);
95 static long mips_elf64_get_dynamic_reloc_upper_bound
97 static long mips_elf64_canonicalize_dynamic_reloc
98 (bfd
*, arelent
**, asymbol
**);
99 static bfd_boolean mips_elf64_slurp_one_reloc_table
100 (bfd
*, asection
*, Elf_Internal_Shdr
*, bfd_size_type
, arelent
*,
101 asymbol
**, bfd_boolean
);
102 static bfd_boolean mips_elf64_slurp_reloc_table
103 (bfd
*, asection
*, asymbol
**, bfd_boolean
);
104 static void mips_elf64_write_relocs
105 (bfd
*, asection
*, void *);
106 static void mips_elf64_write_rel
107 (bfd
*, asection
*, Elf_Internal_Shdr
*, int *, void *);
108 static void mips_elf64_write_rela
109 (bfd
*, asection
*, Elf_Internal_Shdr
*, int *, void *);
110 static bfd_reloc_status_type mips_elf64_gprel16_reloc
111 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
112 static bfd_reloc_status_type mips_elf64_literal_reloc
113 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
114 static bfd_reloc_status_type mips_elf64_gprel32_reloc
115 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
116 static bfd_reloc_status_type mips_elf64_shift6_reloc
117 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
118 static bfd_reloc_status_type mips16_gprel_reloc
119 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
120 static bfd_boolean mips_elf64_assign_gp
122 static bfd_reloc_status_type mips_elf64_final_gp
123 (bfd
*, asymbol
*, bfd_boolean
, char **, bfd_vma
*);
124 static bfd_boolean mips_elf64_object_p
126 static irix_compat_t elf64_mips_irix_compat
128 static bfd_boolean elf64_mips_grok_prstatus
129 (bfd
*, Elf_Internal_Note
*);
130 static bfd_boolean elf64_mips_grok_psinfo
131 (bfd
*, Elf_Internal_Note
*);
133 extern const bfd_target bfd_elf64_bigmips_vec
;
134 extern const bfd_target bfd_elf64_littlemips_vec
;
136 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
137 from smaller values. Start with zero, widen, *then* decrement. */
138 #define MINUS_ONE (((bfd_vma)0) - 1)
140 /* The number of local .got entries we reserve. */
141 #define MIPS_RESERVED_GOTNO (2)
143 /* The relocation table used for SHT_REL sections. */
145 static reloc_howto_type mips_elf64_howto_table_rel
[] =
148 HOWTO (R_MIPS_NONE
, /* type */
150 0, /* size (0 = byte, 1 = short, 2 = long) */
152 FALSE
, /* pc_relative */
154 complain_overflow_dont
, /* complain_on_overflow */
155 _bfd_mips_elf_generic_reloc
, /* special_function */
156 "R_MIPS_NONE", /* name */
157 FALSE
, /* partial_inplace */
160 FALSE
), /* pcrel_offset */
162 /* 16 bit relocation. */
163 HOWTO (R_MIPS_16
, /* type */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
167 FALSE
, /* pc_relative */
169 complain_overflow_signed
, /* complain_on_overflow */
170 _bfd_mips_elf_generic_reloc
, /* special_function */
171 "R_MIPS_16", /* name */
172 TRUE
, /* partial_inplace */
173 0x0000ffff, /* src_mask */
174 0x0000ffff, /* dst_mask */
175 FALSE
), /* pcrel_offset */
177 /* 32 bit relocation. */
178 HOWTO (R_MIPS_32
, /* type */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
182 FALSE
, /* pc_relative */
184 complain_overflow_dont
, /* complain_on_overflow */
185 _bfd_mips_elf_generic_reloc
, /* special_function */
186 "R_MIPS_32", /* name */
187 TRUE
, /* partial_inplace */
188 0xffffffff, /* src_mask */
189 0xffffffff, /* dst_mask */
190 FALSE
), /* pcrel_offset */
192 /* 32 bit symbol relative relocation. */
193 HOWTO (R_MIPS_REL32
, /* type */
195 2, /* size (0 = byte, 1 = short, 2 = long) */
197 FALSE
, /* pc_relative */
199 complain_overflow_dont
, /* complain_on_overflow */
200 _bfd_mips_elf_generic_reloc
, /* special_function */
201 "R_MIPS_REL32", /* name */
202 TRUE
, /* partial_inplace */
203 0xffffffff, /* src_mask */
204 0xffffffff, /* dst_mask */
205 FALSE
), /* pcrel_offset */
207 /* 26 bit jump address. */
208 HOWTO (R_MIPS_26
, /* type */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
212 FALSE
, /* pc_relative */
214 complain_overflow_dont
, /* complain_on_overflow */
215 /* This needs complex overflow
216 detection, because the upper 36
217 bits must match the PC + 4. */
218 _bfd_mips_elf_generic_reloc
, /* special_function */
219 "R_MIPS_26", /* name */
220 TRUE
, /* partial_inplace */
221 0x03ffffff, /* src_mask */
222 0x03ffffff, /* dst_mask */
223 FALSE
), /* pcrel_offset */
225 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
226 However, the native IRIX6 tools use them, so we try our best. */
228 /* High 16 bits of symbol value. */
229 HOWTO (R_MIPS_HI16
, /* type */
231 2, /* size (0 = byte, 1 = short, 2 = long) */
233 FALSE
, /* pc_relative */
235 complain_overflow_dont
, /* complain_on_overflow */
236 _bfd_mips_elf_hi16_reloc
, /* special_function */
237 "R_MIPS_HI16", /* name */
238 TRUE
, /* partial_inplace */
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
241 FALSE
), /* pcrel_offset */
243 /* Low 16 bits of symbol value. */
244 HOWTO (R_MIPS_LO16
, /* type */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
248 FALSE
, /* pc_relative */
250 complain_overflow_dont
, /* complain_on_overflow */
251 _bfd_mips_elf_lo16_reloc
, /* special_function */
252 "R_MIPS_LO16", /* name */
253 TRUE
, /* partial_inplace */
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
256 FALSE
), /* pcrel_offset */
258 /* GP relative reference. */
259 HOWTO (R_MIPS_GPREL16
, /* type */
261 2, /* size (0 = byte, 1 = short, 2 = long) */
263 FALSE
, /* pc_relative */
265 complain_overflow_signed
, /* complain_on_overflow */
266 mips_elf64_gprel16_reloc
, /* special_function */
267 "R_MIPS_GPREL16", /* name */
268 TRUE
, /* partial_inplace */
269 0x0000ffff, /* src_mask */
270 0x0000ffff, /* dst_mask */
271 FALSE
), /* pcrel_offset */
273 /* Reference to literal section. */
274 HOWTO (R_MIPS_LITERAL
, /* type */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
278 FALSE
, /* pc_relative */
280 complain_overflow_signed
, /* complain_on_overflow */
281 mips_elf64_literal_reloc
, /* special_function */
282 "R_MIPS_LITERAL", /* name */
283 TRUE
, /* partial_inplace */
284 0x0000ffff, /* src_mask */
285 0x0000ffff, /* dst_mask */
286 FALSE
), /* pcrel_offset */
288 /* Reference to global offset table. */
289 HOWTO (R_MIPS_GOT16
, /* type */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
293 FALSE
, /* pc_relative */
295 complain_overflow_signed
, /* complain_on_overflow */
296 _bfd_mips_elf_got16_reloc
, /* special_function */
297 "R_MIPS_GOT16", /* name */
298 TRUE
, /* partial_inplace */
299 0x0000ffff, /* src_mask */
300 0x0000ffff, /* dst_mask */
301 FALSE
), /* pcrel_offset */
303 /* 16 bit PC relative reference. Note that the ABI document has a typo
304 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
305 We do the right thing here. */
306 HOWTO (R_MIPS_PC16
, /* type */
308 2, /* size (0 = byte, 1 = short, 2 = long) */
310 TRUE
, /* pc_relative */
312 complain_overflow_signed
, /* complain_on_overflow */
313 _bfd_mips_elf_generic_reloc
, /* special_function */
314 "R_MIPS_PC16", /* name */
315 TRUE
, /* partial_inplace */
316 0x0000ffff, /* src_mask */
317 0x0000ffff, /* dst_mask */
318 TRUE
), /* pcrel_offset */
320 /* 16 bit call through global offset table. */
321 HOWTO (R_MIPS_CALL16
, /* type */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
325 FALSE
, /* pc_relative */
327 complain_overflow_signed
, /* complain_on_overflow */
328 _bfd_mips_elf_generic_reloc
, /* special_function */
329 "R_MIPS_CALL16", /* name */
330 TRUE
, /* partial_inplace */
331 0x0000ffff, /* src_mask */
332 0x0000ffff, /* dst_mask */
333 FALSE
), /* pcrel_offset */
335 /* 32 bit GP relative reference. */
336 HOWTO (R_MIPS_GPREL32
, /* type */
338 2, /* size (0 = byte, 1 = short, 2 = long) */
340 FALSE
, /* pc_relative */
342 complain_overflow_dont
, /* complain_on_overflow */
343 mips_elf64_gprel32_reloc
, /* special_function */
344 "R_MIPS_GPREL32", /* name */
345 TRUE
, /* partial_inplace */
346 0xffffffff, /* src_mask */
347 0xffffffff, /* dst_mask */
348 FALSE
), /* pcrel_offset */
354 /* A 5 bit shift field. */
355 HOWTO (R_MIPS_SHIFT5
, /* type */
357 2, /* size (0 = byte, 1 = short, 2 = long) */
359 FALSE
, /* pc_relative */
361 complain_overflow_bitfield
, /* complain_on_overflow */
362 _bfd_mips_elf_generic_reloc
, /* special_function */
363 "R_MIPS_SHIFT5", /* name */
364 TRUE
, /* partial_inplace */
365 0x000007c0, /* src_mask */
366 0x000007c0, /* dst_mask */
367 FALSE
), /* pcrel_offset */
369 /* A 6 bit shift field. */
370 HOWTO (R_MIPS_SHIFT6
, /* type */
372 2, /* size (0 = byte, 1 = short, 2 = long) */
374 FALSE
, /* pc_relative */
376 complain_overflow_bitfield
, /* complain_on_overflow */
377 mips_elf64_shift6_reloc
, /* special_function */
378 "R_MIPS_SHIFT6", /* name */
379 TRUE
, /* partial_inplace */
380 0x000007c4, /* src_mask */
381 0x000007c4, /* dst_mask */
382 FALSE
), /* pcrel_offset */
384 /* 64 bit relocation. */
385 HOWTO (R_MIPS_64
, /* type */
387 4, /* size (0 = byte, 1 = short, 2 = long) */
389 FALSE
, /* pc_relative */
391 complain_overflow_dont
, /* complain_on_overflow */
392 _bfd_mips_elf_generic_reloc
, /* special_function */
393 "R_MIPS_64", /* name */
394 TRUE
, /* partial_inplace */
395 MINUS_ONE
, /* src_mask */
396 MINUS_ONE
, /* dst_mask */
397 FALSE
), /* pcrel_offset */
399 /* Displacement in the global offset table. */
400 HOWTO (R_MIPS_GOT_DISP
, /* type */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
404 FALSE
, /* pc_relative */
406 complain_overflow_signed
, /* complain_on_overflow */
407 _bfd_mips_elf_generic_reloc
, /* special_function */
408 "R_MIPS_GOT_DISP", /* name */
409 TRUE
, /* partial_inplace */
410 0x0000ffff, /* src_mask */
411 0x0000ffff, /* dst_mask */
412 FALSE
), /* pcrel_offset */
414 /* Displacement to page pointer in the global offset table. */
415 HOWTO (R_MIPS_GOT_PAGE
, /* type */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
419 FALSE
, /* pc_relative */
421 complain_overflow_signed
, /* complain_on_overflow */
422 _bfd_mips_elf_generic_reloc
, /* special_function */
423 "R_MIPS_GOT_PAGE", /* name */
424 TRUE
, /* partial_inplace */
425 0x0000ffff, /* src_mask */
426 0x0000ffff, /* dst_mask */
427 FALSE
), /* pcrel_offset */
429 /* Offset from page pointer in the global offset table. */
430 HOWTO (R_MIPS_GOT_OFST
, /* type */
432 2, /* size (0 = byte, 1 = short, 2 = long) */
434 FALSE
, /* pc_relative */
436 complain_overflow_signed
, /* complain_on_overflow */
437 _bfd_mips_elf_generic_reloc
, /* special_function */
438 "R_MIPS_GOT_OFST", /* name */
439 TRUE
, /* partial_inplace */
440 0x0000ffff, /* src_mask */
441 0x0000ffff, /* dst_mask */
442 FALSE
), /* pcrel_offset */
444 /* High 16 bits of displacement in global offset table. */
445 HOWTO (R_MIPS_GOT_HI16
, /* type */
447 2, /* size (0 = byte, 1 = short, 2 = long) */
449 FALSE
, /* pc_relative */
451 complain_overflow_dont
, /* complain_on_overflow */
452 _bfd_mips_elf_generic_reloc
, /* special_function */
453 "R_MIPS_GOT_HI16", /* name */
454 TRUE
, /* partial_inplace */
455 0x0000ffff, /* src_mask */
456 0x0000ffff, /* dst_mask */
457 FALSE
), /* pcrel_offset */
459 /* Low 16 bits of displacement in global offset table. */
460 HOWTO (R_MIPS_GOT_LO16
, /* type */
462 2, /* size (0 = byte, 1 = short, 2 = long) */
464 FALSE
, /* pc_relative */
466 complain_overflow_dont
, /* complain_on_overflow */
467 _bfd_mips_elf_generic_reloc
, /* special_function */
468 "R_MIPS_GOT_LO16", /* name */
469 TRUE
, /* partial_inplace */
470 0x0000ffff, /* src_mask */
471 0x0000ffff, /* dst_mask */
472 FALSE
), /* pcrel_offset */
474 /* 64 bit subtraction. */
475 HOWTO (R_MIPS_SUB
, /* type */
477 4, /* size (0 = byte, 1 = short, 2 = long) */
479 FALSE
, /* pc_relative */
481 complain_overflow_dont
, /* complain_on_overflow */
482 _bfd_mips_elf_generic_reloc
, /* special_function */
483 "R_MIPS_SUB", /* name */
484 TRUE
, /* partial_inplace */
485 MINUS_ONE
, /* src_mask */
486 MINUS_ONE
, /* dst_mask */
487 FALSE
), /* pcrel_offset */
489 /* Insert the addend as an instruction. */
490 /* FIXME: Not handled correctly. */
491 HOWTO (R_MIPS_INSERT_A
, /* type */
493 2, /* size (0 = byte, 1 = short, 2 = long) */
495 FALSE
, /* pc_relative */
497 complain_overflow_dont
, /* complain_on_overflow */
498 _bfd_mips_elf_generic_reloc
, /* special_function */
499 "R_MIPS_INSERT_A", /* name */
500 TRUE
, /* partial_inplace */
501 0xffffffff, /* src_mask */
502 0xffffffff, /* dst_mask */
503 FALSE
), /* pcrel_offset */
505 /* Insert the addend as an instruction, and change all relocations
506 to refer to the old instruction at the address. */
507 /* FIXME: Not handled correctly. */
508 HOWTO (R_MIPS_INSERT_B
, /* type */
510 2, /* size (0 = byte, 1 = short, 2 = long) */
512 FALSE
, /* pc_relative */
514 complain_overflow_dont
, /* complain_on_overflow */
515 _bfd_mips_elf_generic_reloc
, /* special_function */
516 "R_MIPS_INSERT_B", /* name */
517 TRUE
, /* partial_inplace */
518 0xffffffff, /* src_mask */
519 0xffffffff, /* dst_mask */
520 FALSE
), /* pcrel_offset */
522 /* Delete a 32 bit instruction. */
523 /* FIXME: Not handled correctly. */
524 HOWTO (R_MIPS_DELETE
, /* type */
526 2, /* size (0 = byte, 1 = short, 2 = long) */
528 FALSE
, /* pc_relative */
530 complain_overflow_dont
, /* complain_on_overflow */
531 _bfd_mips_elf_generic_reloc
, /* special_function */
532 "R_MIPS_DELETE", /* name */
533 TRUE
, /* partial_inplace */
534 0xffffffff, /* src_mask */
535 0xffffffff, /* dst_mask */
536 FALSE
), /* pcrel_offset */
538 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
540 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
541 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
543 b) No other NewABI toolchain actually emits such relocations. */
544 EMPTY_HOWTO (R_MIPS_HIGHER
),
545 EMPTY_HOWTO (R_MIPS_HIGHEST
),
547 /* High 16 bits of displacement in global offset table. */
548 HOWTO (R_MIPS_CALL_HI16
, /* type */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
552 FALSE
, /* pc_relative */
554 complain_overflow_dont
, /* complain_on_overflow */
555 _bfd_mips_elf_generic_reloc
, /* special_function */
556 "R_MIPS_CALL_HI16", /* name */
557 TRUE
, /* partial_inplace */
558 0x0000ffff, /* src_mask */
559 0x0000ffff, /* dst_mask */
560 FALSE
), /* pcrel_offset */
562 /* Low 16 bits of displacement in global offset table. */
563 HOWTO (R_MIPS_CALL_LO16
, /* type */
565 2, /* size (0 = byte, 1 = short, 2 = long) */
567 FALSE
, /* pc_relative */
569 complain_overflow_dont
, /* complain_on_overflow */
570 _bfd_mips_elf_generic_reloc
, /* special_function */
571 "R_MIPS_CALL_LO16", /* name */
572 TRUE
, /* partial_inplace */
573 0x0000ffff, /* src_mask */
574 0x0000ffff, /* dst_mask */
575 FALSE
), /* pcrel_offset */
577 /* Section displacement, used by an associated event location section. */
578 HOWTO (R_MIPS_SCN_DISP
, /* type */
580 2, /* size (0 = byte, 1 = short, 2 = long) */
582 FALSE
, /* pc_relative */
584 complain_overflow_dont
, /* complain_on_overflow */
585 _bfd_mips_elf_generic_reloc
, /* special_function */
586 "R_MIPS_SCN_DISP", /* name */
587 TRUE
, /* partial_inplace */
588 0xffffffff, /* src_mask */
589 0xffffffff, /* dst_mask */
590 FALSE
), /* pcrel_offset */
592 HOWTO (R_MIPS_REL16
, /* type */
594 1, /* size (0 = byte, 1 = short, 2 = long) */
596 FALSE
, /* pc_relative */
598 complain_overflow_signed
, /* complain_on_overflow */
599 _bfd_mips_elf_generic_reloc
, /* special_function */
600 "R_MIPS_REL16", /* name */
601 TRUE
, /* partial_inplace */
602 0xffff, /* src_mask */
603 0xffff, /* dst_mask */
604 FALSE
), /* pcrel_offset */
606 /* These two are obsolete. */
607 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
608 EMPTY_HOWTO (R_MIPS_PJUMP
),
610 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
611 It must be used for multigot GOT's (and only there). */
612 HOWTO (R_MIPS_RELGOT
, /* type */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
616 FALSE
, /* pc_relative */
618 complain_overflow_dont
, /* complain_on_overflow */
619 _bfd_mips_elf_generic_reloc
, /* special_function */
620 "R_MIPS_RELGOT", /* name */
621 TRUE
, /* partial_inplace */
622 0xffffffff, /* src_mask */
623 0xffffffff, /* dst_mask */
624 FALSE
), /* pcrel_offset */
626 /* Protected jump conversion. This is an optimization hint. No
627 relocation is required for correctness. */
628 HOWTO (R_MIPS_JALR
, /* type */
630 2, /* size (0 = byte, 1 = short, 2 = long) */
632 FALSE
, /* pc_relative */
634 complain_overflow_dont
, /* complain_on_overflow */
635 _bfd_mips_elf_generic_reloc
, /* special_function */
636 "R_MIPS_JALR", /* name */
637 FALSE
, /* partial_inplace */
639 0x00000000, /* dst_mask */
640 FALSE
), /* pcrel_offset */
642 /* TLS relocations. */
643 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32
),
644 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32
),
646 HOWTO (R_MIPS_TLS_DTPMOD64
, /* type */
648 4, /* size (0 = byte, 1 = short, 2 = long) */
650 FALSE
, /* pc_relative */
652 complain_overflow_dont
, /* complain_on_overflow */
653 _bfd_mips_elf_generic_reloc
, /* special_function */
654 "R_MIPS_TLS_DTPMOD64", /* name */
655 TRUE
, /* partial_inplace */
656 MINUS_ONE
, /* src_mask */
657 MINUS_ONE
, /* dst_mask */
658 FALSE
), /* pcrel_offset */
660 HOWTO (R_MIPS_TLS_DTPREL64
, /* type */
662 4, /* size (0 = byte, 1 = short, 2 = long) */
664 FALSE
, /* pc_relative */
666 complain_overflow_dont
, /* complain_on_overflow */
667 _bfd_mips_elf_generic_reloc
, /* special_function */
668 "R_MIPS_TLS_DTPREL64", /* name */
669 TRUE
, /* partial_inplace */
670 MINUS_ONE
, /* src_mask */
671 MINUS_ONE
, /* dst_mask */
672 FALSE
), /* pcrel_offset */
674 /* TLS general dynamic variable reference. */
675 HOWTO (R_MIPS_TLS_GD
, /* type */
677 2, /* size (0 = byte, 1 = short, 2 = long) */
679 FALSE
, /* pc_relative */
681 complain_overflow_signed
, /* complain_on_overflow */
682 _bfd_mips_elf_generic_reloc
, /* special_function */
683 "R_MIPS_TLS_GD", /* name */
684 TRUE
, /* partial_inplace */
685 0x0000ffff, /* src_mask */
686 0x0000ffff, /* dst_mask */
687 FALSE
), /* pcrel_offset */
689 /* TLS local dynamic variable reference. */
690 HOWTO (R_MIPS_TLS_LDM
, /* type */
692 2, /* size (0 = byte, 1 = short, 2 = long) */
694 FALSE
, /* pc_relative */
696 complain_overflow_signed
, /* complain_on_overflow */
697 _bfd_mips_elf_generic_reloc
, /* special_function */
698 "R_MIPS_TLS_LDM", /* name */
699 TRUE
, /* partial_inplace */
700 0x0000ffff, /* src_mask */
701 0x0000ffff, /* dst_mask */
702 FALSE
), /* pcrel_offset */
704 /* TLS local dynamic offset. */
705 HOWTO (R_MIPS_TLS_DTPREL_HI16
, /* type */
707 2, /* size (0 = byte, 1 = short, 2 = long) */
709 FALSE
, /* pc_relative */
711 complain_overflow_signed
, /* complain_on_overflow */
712 _bfd_mips_elf_generic_reloc
, /* special_function */
713 "R_MIPS_TLS_DTPREL_HI16", /* name */
714 TRUE
, /* partial_inplace */
715 0x0000ffff, /* src_mask */
716 0x0000ffff, /* dst_mask */
717 FALSE
), /* pcrel_offset */
719 /* TLS local dynamic offset. */
720 HOWTO (R_MIPS_TLS_DTPREL_LO16
, /* type */
722 2, /* size (0 = byte, 1 = short, 2 = long) */
724 FALSE
, /* pc_relative */
726 complain_overflow_signed
, /* complain_on_overflow */
727 _bfd_mips_elf_generic_reloc
, /* special_function */
728 "R_MIPS_TLS_DTPREL_LO16", /* name */
729 TRUE
, /* partial_inplace */
730 0x0000ffff, /* src_mask */
731 0x0000ffff, /* dst_mask */
732 FALSE
), /* pcrel_offset */
734 /* TLS thread pointer offset. */
735 HOWTO (R_MIPS_TLS_GOTTPREL
, /* type */
737 2, /* size (0 = byte, 1 = short, 2 = long) */
739 FALSE
, /* pc_relative */
741 complain_overflow_signed
, /* complain_on_overflow */
742 _bfd_mips_elf_generic_reloc
, /* special_function */
743 "R_MIPS_TLS_GOTTPREL", /* name */
744 TRUE
, /* partial_inplace */
745 0x0000ffff, /* src_mask */
746 0x0000ffff, /* dst_mask */
747 FALSE
), /* pcrel_offset */
749 /* TLS IE dynamic relocations. */
750 EMPTY_HOWTO (R_MIPS_TLS_TPREL32
),
752 HOWTO (R_MIPS_TLS_TPREL64
, /* type */
754 4, /* size (0 = byte, 1 = short, 2 = long) */
756 FALSE
, /* pc_relative */
758 complain_overflow_dont
, /* complain_on_overflow */
759 _bfd_mips_elf_generic_reloc
, /* special_function */
760 "R_MIPS_TLS_TPREL64", /* name */
761 TRUE
, /* partial_inplace */
762 MINUS_ONE
, /* src_mask */
763 MINUS_ONE
, /* dst_mask */
764 FALSE
), /* pcrel_offset */
766 /* TLS thread pointer offset. */
767 HOWTO (R_MIPS_TLS_TPREL_HI16
, /* type */
769 2, /* size (0 = byte, 1 = short, 2 = long) */
771 FALSE
, /* pc_relative */
773 complain_overflow_signed
, /* complain_on_overflow */
774 _bfd_mips_elf_generic_reloc
, /* special_function */
775 "R_MIPS_TLS_TPREL_HI16", /* name */
776 TRUE
, /* partial_inplace */
777 0x0000ffff, /* src_mask */
778 0x0000ffff, /* dst_mask */
779 FALSE
), /* pcrel_offset */
781 /* TLS thread pointer offset. */
782 HOWTO (R_MIPS_TLS_TPREL_LO16
, /* type */
784 2, /* size (0 = byte, 1 = short, 2 = long) */
786 FALSE
, /* pc_relative */
788 complain_overflow_signed
, /* complain_on_overflow */
789 _bfd_mips_elf_generic_reloc
, /* special_function */
790 "R_MIPS_TLS_TPREL_LO16", /* name */
791 TRUE
, /* partial_inplace */
792 0x0000ffff, /* src_mask */
793 0x0000ffff, /* dst_mask */
794 FALSE
), /* pcrel_offset */
796 /* 32 bit relocation with no addend. */
797 HOWTO (R_MIPS_GLOB_DAT
, /* type */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
801 FALSE
, /* pc_relative */
803 complain_overflow_dont
, /* complain_on_overflow */
804 _bfd_mips_elf_generic_reloc
, /* special_function */
805 "R_MIPS_GLOB_DAT", /* name */
806 FALSE
, /* partial_inplace */
808 0xffffffff, /* dst_mask */
809 FALSE
), /* pcrel_offset */
812 /* The relocation table used for SHT_RELA sections. */
814 static reloc_howto_type mips_elf64_howto_table_rela
[] =
817 HOWTO (R_MIPS_NONE
, /* type */
819 0, /* size (0 = byte, 1 = short, 2 = long) */
821 FALSE
, /* pc_relative */
823 complain_overflow_dont
, /* complain_on_overflow */
824 _bfd_mips_elf_generic_reloc
, /* special_function */
825 "R_MIPS_NONE", /* name */
826 FALSE
, /* partial_inplace */
829 FALSE
), /* pcrel_offset */
831 /* 16 bit relocation. */
832 HOWTO (R_MIPS_16
, /* type */
834 2, /* size (0 = byte, 1 = short, 2 = long) */
836 FALSE
, /* pc_relative */
838 complain_overflow_signed
, /* complain_on_overflow */
839 _bfd_mips_elf_generic_reloc
, /* special_function */
840 "R_MIPS_16", /* name */
841 FALSE
, /* partial_inplace */
843 0x0000ffff, /* dst_mask */
844 FALSE
), /* pcrel_offset */
846 /* 32 bit relocation. */
847 HOWTO (R_MIPS_32
, /* type */
849 2, /* size (0 = byte, 1 = short, 2 = long) */
851 FALSE
, /* pc_relative */
853 complain_overflow_dont
, /* complain_on_overflow */
854 _bfd_mips_elf_generic_reloc
, /* special_function */
855 "R_MIPS_32", /* name */
856 FALSE
, /* partial_inplace */
858 0xffffffff, /* dst_mask */
859 FALSE
), /* pcrel_offset */
861 /* 32 bit symbol relative relocation. */
862 HOWTO (R_MIPS_REL32
, /* type */
864 2, /* size (0 = byte, 1 = short, 2 = long) */
866 FALSE
, /* pc_relative */
868 complain_overflow_dont
, /* complain_on_overflow */
869 _bfd_mips_elf_generic_reloc
, /* special_function */
870 "R_MIPS_REL32", /* name */
871 FALSE
, /* partial_inplace */
873 0xffffffff, /* dst_mask */
874 FALSE
), /* pcrel_offset */
876 /* 26 bit jump address. */
877 HOWTO (R_MIPS_26
, /* type */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
881 FALSE
, /* pc_relative */
883 complain_overflow_dont
, /* complain_on_overflow */
884 /* This needs complex overflow
885 detection, because the upper 36
886 bits must match the PC + 4. */
887 _bfd_mips_elf_generic_reloc
, /* special_function */
888 "R_MIPS_26", /* name */
889 FALSE
, /* partial_inplace */
891 0x03ffffff, /* dst_mask */
892 FALSE
), /* pcrel_offset */
894 /* High 16 bits of symbol value. */
895 HOWTO (R_MIPS_HI16
, /* type */
897 2, /* size (0 = byte, 1 = short, 2 = long) */
899 FALSE
, /* pc_relative */
901 complain_overflow_dont
, /* complain_on_overflow */
902 _bfd_mips_elf_generic_reloc
, /* special_function */
903 "R_MIPS_HI16", /* name */
904 FALSE
, /* partial_inplace */
906 0x0000ffff, /* dst_mask */
907 FALSE
), /* pcrel_offset */
909 /* Low 16 bits of symbol value. */
910 HOWTO (R_MIPS_LO16
, /* type */
912 2, /* size (0 = byte, 1 = short, 2 = long) */
914 FALSE
, /* pc_relative */
916 complain_overflow_dont
, /* complain_on_overflow */
917 _bfd_mips_elf_generic_reloc
, /* special_function */
918 "R_MIPS_LO16", /* name */
919 FALSE
, /* partial_inplace */
921 0x0000ffff, /* dst_mask */
922 FALSE
), /* pcrel_offset */
924 /* GP relative reference. */
925 HOWTO (R_MIPS_GPREL16
, /* type */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
929 FALSE
, /* pc_relative */
931 complain_overflow_signed
, /* complain_on_overflow */
932 mips_elf64_gprel16_reloc
, /* special_function */
933 "R_MIPS_GPREL16", /* name */
934 FALSE
, /* partial_inplace */
936 0x0000ffff, /* dst_mask */
937 FALSE
), /* pcrel_offset */
939 /* Reference to literal section. */
940 HOWTO (R_MIPS_LITERAL
, /* type */
942 2, /* size (0 = byte, 1 = short, 2 = long) */
944 FALSE
, /* pc_relative */
946 complain_overflow_signed
, /* complain_on_overflow */
947 mips_elf64_literal_reloc
, /* special_function */
948 "R_MIPS_LITERAL", /* name */
949 FALSE
, /* partial_inplace */
951 0x0000ffff, /* dst_mask */
952 FALSE
), /* pcrel_offset */
954 /* Reference to global offset table. */
955 HOWTO (R_MIPS_GOT16
, /* type */
957 2, /* size (0 = byte, 1 = short, 2 = long) */
959 FALSE
, /* pc_relative */
961 complain_overflow_signed
, /* complain_on_overflow */
962 _bfd_mips_elf_generic_reloc
, /* special_function */
963 "R_MIPS_GOT16", /* name */
964 FALSE
, /* partial_inplace */
966 0x0000ffff, /* dst_mask */
967 FALSE
), /* pcrel_offset */
969 /* 16 bit PC relative reference. Note that the ABI document has a typo
970 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
971 We do the right thing here. */
972 HOWTO (R_MIPS_PC16
, /* type */
974 2, /* size (0 = byte, 1 = short, 2 = long) */
976 TRUE
, /* pc_relative */
978 complain_overflow_signed
, /* complain_on_overflow */
979 _bfd_mips_elf_generic_reloc
, /* special_function */
980 "R_MIPS_PC16", /* name */
981 FALSE
, /* partial_inplace */
983 0x0000ffff, /* dst_mask */
984 TRUE
), /* pcrel_offset */
986 /* 16 bit call through global offset table. */
987 HOWTO (R_MIPS_CALL16
, /* type */
989 2, /* size (0 = byte, 1 = short, 2 = long) */
991 FALSE
, /* pc_relative */
993 complain_overflow_signed
, /* complain_on_overflow */
994 _bfd_mips_elf_generic_reloc
, /* special_function */
995 "R_MIPS_CALL16", /* name */
996 FALSE
, /* partial_inplace */
998 0x0000ffff, /* dst_mask */
999 FALSE
), /* pcrel_offset */
1001 /* 32 bit GP relative reference. */
1002 HOWTO (R_MIPS_GPREL32
, /* type */
1004 2, /* size (0 = byte, 1 = short, 2 = long) */
1006 FALSE
, /* pc_relative */
1008 complain_overflow_dont
, /* complain_on_overflow */
1009 mips_elf64_gprel32_reloc
, /* special_function */
1010 "R_MIPS_GPREL32", /* name */
1011 FALSE
, /* partial_inplace */
1013 0xffffffff, /* dst_mask */
1014 FALSE
), /* pcrel_offset */
1020 /* A 5 bit shift field. */
1021 HOWTO (R_MIPS_SHIFT5
, /* type */
1023 2, /* size (0 = byte, 1 = short, 2 = long) */
1025 FALSE
, /* pc_relative */
1027 complain_overflow_bitfield
, /* complain_on_overflow */
1028 _bfd_mips_elf_generic_reloc
, /* special_function */
1029 "R_MIPS_SHIFT5", /* name */
1030 FALSE
, /* partial_inplace */
1032 0x000007c0, /* dst_mask */
1033 FALSE
), /* pcrel_offset */
1035 /* A 6 bit shift field. */
1036 HOWTO (R_MIPS_SHIFT6
, /* type */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1040 FALSE
, /* pc_relative */
1042 complain_overflow_bitfield
, /* complain_on_overflow */
1043 mips_elf64_shift6_reloc
, /* special_function */
1044 "R_MIPS_SHIFT6", /* name */
1045 FALSE
, /* partial_inplace */
1047 0x000007c4, /* dst_mask */
1048 FALSE
), /* pcrel_offset */
1050 /* 64 bit relocation. */
1051 HOWTO (R_MIPS_64
, /* type */
1053 4, /* size (0 = byte, 1 = short, 2 = long) */
1055 FALSE
, /* pc_relative */
1057 complain_overflow_dont
, /* complain_on_overflow */
1058 _bfd_mips_elf_generic_reloc
, /* special_function */
1059 "R_MIPS_64", /* name */
1060 FALSE
, /* partial_inplace */
1062 MINUS_ONE
, /* dst_mask */
1063 FALSE
), /* pcrel_offset */
1065 /* Displacement in the global offset table. */
1066 HOWTO (R_MIPS_GOT_DISP
, /* type */
1068 2, /* size (0 = byte, 1 = short, 2 = long) */
1070 FALSE
, /* pc_relative */
1072 complain_overflow_signed
, /* complain_on_overflow */
1073 _bfd_mips_elf_generic_reloc
, /* special_function */
1074 "R_MIPS_GOT_DISP", /* name */
1075 FALSE
, /* partial_inplace */
1077 0x0000ffff, /* dst_mask */
1078 FALSE
), /* pcrel_offset */
1080 /* Displacement to page pointer in the global offset table. */
1081 HOWTO (R_MIPS_GOT_PAGE
, /* type */
1083 2, /* size (0 = byte, 1 = short, 2 = long) */
1085 FALSE
, /* pc_relative */
1087 complain_overflow_signed
, /* complain_on_overflow */
1088 _bfd_mips_elf_generic_reloc
, /* special_function */
1089 "R_MIPS_GOT_PAGE", /* name */
1090 FALSE
, /* partial_inplace */
1092 0x0000ffff, /* dst_mask */
1093 FALSE
), /* pcrel_offset */
1095 /* Offset from page pointer in the global offset table. */
1096 HOWTO (R_MIPS_GOT_OFST
, /* type */
1098 2, /* size (0 = byte, 1 = short, 2 = long) */
1100 FALSE
, /* pc_relative */
1102 complain_overflow_signed
, /* complain_on_overflow */
1103 _bfd_mips_elf_generic_reloc
, /* special_function */
1104 "R_MIPS_GOT_OFST", /* name */
1105 FALSE
, /* partial_inplace */
1107 0x0000ffff, /* dst_mask */
1108 FALSE
), /* pcrel_offset */
1110 /* High 16 bits of displacement in global offset table. */
1111 HOWTO (R_MIPS_GOT_HI16
, /* type */
1113 2, /* size (0 = byte, 1 = short, 2 = long) */
1115 FALSE
, /* pc_relative */
1117 complain_overflow_dont
, /* complain_on_overflow */
1118 _bfd_mips_elf_generic_reloc
, /* special_function */
1119 "R_MIPS_GOT_HI16", /* name */
1120 FALSE
, /* partial_inplace */
1122 0x0000ffff, /* dst_mask */
1123 FALSE
), /* pcrel_offset */
1125 /* Low 16 bits of displacement in global offset table. */
1126 HOWTO (R_MIPS_GOT_LO16
, /* type */
1128 2, /* size (0 = byte, 1 = short, 2 = long) */
1130 FALSE
, /* pc_relative */
1132 complain_overflow_dont
, /* complain_on_overflow */
1133 _bfd_mips_elf_generic_reloc
, /* special_function */
1134 "R_MIPS_GOT_LO16", /* name */
1135 FALSE
, /* partial_inplace */
1137 0x0000ffff, /* dst_mask */
1138 FALSE
), /* pcrel_offset */
1140 /* 64 bit subtraction. */
1141 HOWTO (R_MIPS_SUB
, /* type */
1143 4, /* 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_SUB", /* name */
1150 FALSE
, /* partial_inplace */
1152 MINUS_ONE
, /* dst_mask */
1153 FALSE
), /* pcrel_offset */
1155 /* Insert the addend as an instruction. */
1156 /* FIXME: Not handled correctly. */
1157 HOWTO (R_MIPS_INSERT_A
, /* type */
1159 2, /* size (0 = byte, 1 = short, 2 = long) */
1161 FALSE
, /* pc_relative */
1163 complain_overflow_dont
, /* complain_on_overflow */
1164 _bfd_mips_elf_generic_reloc
, /* special_function */
1165 "R_MIPS_INSERT_A", /* name */
1166 FALSE
, /* partial_inplace */
1168 0xffffffff, /* dst_mask */
1169 FALSE
), /* pcrel_offset */
1171 /* Insert the addend as an instruction, and change all relocations
1172 to refer to the old instruction at the address. */
1173 /* FIXME: Not handled correctly. */
1174 HOWTO (R_MIPS_INSERT_B
, /* type */
1176 2, /* size (0 = byte, 1 = short, 2 = long) */
1178 FALSE
, /* pc_relative */
1180 complain_overflow_dont
, /* complain_on_overflow */
1181 _bfd_mips_elf_generic_reloc
, /* special_function */
1182 "R_MIPS_INSERT_B", /* name */
1183 FALSE
, /* partial_inplace */
1185 0xffffffff, /* dst_mask */
1186 FALSE
), /* pcrel_offset */
1188 /* Delete a 32 bit instruction. */
1189 /* FIXME: Not handled correctly. */
1190 HOWTO (R_MIPS_DELETE
, /* type */
1192 2, /* size (0 = byte, 1 = short, 2 = long) */
1194 FALSE
, /* pc_relative */
1196 complain_overflow_dont
, /* complain_on_overflow */
1197 _bfd_mips_elf_generic_reloc
, /* special_function */
1198 "R_MIPS_DELETE", /* name */
1199 FALSE
, /* partial_inplace */
1201 0xffffffff, /* dst_mask */
1202 FALSE
), /* pcrel_offset */
1204 /* Get the higher value of a 64 bit addend. */
1205 HOWTO (R_MIPS_HIGHER
, /* type */
1207 2, /* size (0 = byte, 1 = short, 2 = long) */
1209 FALSE
, /* pc_relative */
1211 complain_overflow_dont
, /* complain_on_overflow */
1212 _bfd_mips_elf_generic_reloc
, /* special_function */
1213 "R_MIPS_HIGHER", /* name */
1214 FALSE
, /* partial_inplace */
1216 0x0000ffff, /* dst_mask */
1217 FALSE
), /* pcrel_offset */
1219 /* Get the highest value of a 64 bit addend. */
1220 HOWTO (R_MIPS_HIGHEST
, /* type */
1222 2, /* size (0 = byte, 1 = short, 2 = long) */
1224 FALSE
, /* pc_relative */
1226 complain_overflow_dont
, /* complain_on_overflow */
1227 _bfd_mips_elf_generic_reloc
, /* special_function */
1228 "R_MIPS_HIGHEST", /* name */
1229 FALSE
, /* partial_inplace */
1231 0x0000ffff, /* dst_mask */
1232 FALSE
), /* pcrel_offset */
1234 /* High 16 bits of displacement in global offset table. */
1235 HOWTO (R_MIPS_CALL_HI16
, /* type */
1237 2, /* size (0 = byte, 1 = short, 2 = long) */
1239 FALSE
, /* pc_relative */
1241 complain_overflow_dont
, /* complain_on_overflow */
1242 _bfd_mips_elf_generic_reloc
, /* special_function */
1243 "R_MIPS_CALL_HI16", /* name */
1244 FALSE
, /* partial_inplace */
1246 0x0000ffff, /* dst_mask */
1247 FALSE
), /* pcrel_offset */
1249 /* Low 16 bits of displacement in global offset table. */
1250 HOWTO (R_MIPS_CALL_LO16
, /* type */
1252 2, /* size (0 = byte, 1 = short, 2 = long) */
1254 FALSE
, /* pc_relative */
1256 complain_overflow_dont
, /* complain_on_overflow */
1257 _bfd_mips_elf_generic_reloc
, /* special_function */
1258 "R_MIPS_CALL_LO16", /* name */
1259 FALSE
, /* partial_inplace */
1261 0x0000ffff, /* dst_mask */
1262 FALSE
), /* pcrel_offset */
1264 /* Section displacement, used by an associated event location section. */
1265 HOWTO (R_MIPS_SCN_DISP
, /* type */
1267 2, /* size (0 = byte, 1 = short, 2 = long) */
1269 FALSE
, /* pc_relative */
1271 complain_overflow_dont
, /* complain_on_overflow */
1272 _bfd_mips_elf_generic_reloc
, /* special_function */
1273 "R_MIPS_SCN_DISP", /* name */
1274 FALSE
, /* partial_inplace */
1276 0xffffffff, /* dst_mask */
1277 FALSE
), /* pcrel_offset */
1279 HOWTO (R_MIPS_REL16
, /* type */
1281 1, /* size (0 = byte, 1 = short, 2 = long) */
1283 FALSE
, /* pc_relative */
1285 complain_overflow_signed
, /* complain_on_overflow */
1286 _bfd_mips_elf_generic_reloc
, /* special_function */
1287 "R_MIPS_REL16", /* name */
1288 FALSE
, /* partial_inplace */
1290 0xffff, /* dst_mask */
1291 FALSE
), /* pcrel_offset */
1293 /* These two are obsolete. */
1294 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
1295 EMPTY_HOWTO (R_MIPS_PJUMP
),
1297 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1298 It must be used for multigot GOT's (and only there). */
1299 HOWTO (R_MIPS_RELGOT
, /* type */
1301 2, /* size (0 = byte, 1 = short, 2 = long) */
1303 FALSE
, /* pc_relative */
1305 complain_overflow_dont
, /* complain_on_overflow */
1306 _bfd_mips_elf_generic_reloc
, /* special_function */
1307 "R_MIPS_RELGOT", /* name */
1308 FALSE
, /* partial_inplace */
1310 0xffffffff, /* dst_mask */
1311 FALSE
), /* pcrel_offset */
1313 /* Protected jump conversion. This is an optimization hint. No
1314 relocation is required for correctness. */
1315 HOWTO (R_MIPS_JALR
, /* type */
1317 2, /* size (0 = byte, 1 = short, 2 = long) */
1319 FALSE
, /* pc_relative */
1321 complain_overflow_dont
, /* complain_on_overflow */
1322 _bfd_mips_elf_generic_reloc
, /* special_function */
1323 "R_MIPS_JALR", /* name */
1324 FALSE
, /* partial_inplace */
1326 0x00000000, /* dst_mask */
1327 FALSE
), /* pcrel_offset */
1329 /* TLS relocations. */
1330 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32
),
1331 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32
),
1333 HOWTO (R_MIPS_TLS_DTPMOD64
, /* type */
1335 4, /* size (0 = byte, 1 = short, 2 = long) */
1337 FALSE
, /* pc_relative */
1339 complain_overflow_dont
, /* complain_on_overflow */
1340 _bfd_mips_elf_generic_reloc
, /* special_function */
1341 "R_MIPS_TLS_DTPMOD64", /* name */
1342 FALSE
, /* partial_inplace */
1343 MINUS_ONE
, /* src_mask */
1344 MINUS_ONE
, /* dst_mask */
1345 FALSE
), /* pcrel_offset */
1347 HOWTO (R_MIPS_TLS_DTPREL64
, /* type */
1349 4, /* size (0 = byte, 1 = short, 2 = long) */
1351 FALSE
, /* pc_relative */
1353 complain_overflow_dont
, /* complain_on_overflow */
1354 _bfd_mips_elf_generic_reloc
, /* special_function */
1355 "R_MIPS_TLS_DTPREL64", /* name */
1356 FALSE
, /* partial_inplace */
1357 MINUS_ONE
, /* src_mask */
1358 MINUS_ONE
, /* dst_mask */
1359 FALSE
), /* pcrel_offset */
1361 /* TLS general dynamic variable reference. */
1362 HOWTO (R_MIPS_TLS_GD
, /* type */
1364 2, /* size (0 = byte, 1 = short, 2 = long) */
1366 FALSE
, /* pc_relative */
1368 complain_overflow_signed
, /* complain_on_overflow */
1369 _bfd_mips_elf_generic_reloc
, /* special_function */
1370 "R_MIPS_TLS_GD", /* name */
1371 FALSE
, /* partial_inplace */
1372 0x0000ffff, /* src_mask */
1373 0x0000ffff, /* dst_mask */
1374 FALSE
), /* pcrel_offset */
1376 /* TLS local dynamic variable reference. */
1377 HOWTO (R_MIPS_TLS_LDM
, /* type */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1381 FALSE
, /* pc_relative */
1383 complain_overflow_signed
, /* complain_on_overflow */
1384 _bfd_mips_elf_generic_reloc
, /* special_function */
1385 "R_MIPS_TLS_LDM", /* name */
1386 FALSE
, /* partial_inplace */
1387 0x0000ffff, /* src_mask */
1388 0x0000ffff, /* dst_mask */
1389 FALSE
), /* pcrel_offset */
1391 /* TLS local dynamic offset. */
1392 HOWTO (R_MIPS_TLS_DTPREL_HI16
, /* type */
1394 2, /* size (0 = byte, 1 = short, 2 = long) */
1396 FALSE
, /* pc_relative */
1398 complain_overflow_signed
, /* complain_on_overflow */
1399 _bfd_mips_elf_generic_reloc
, /* special_function */
1400 "R_MIPS_TLS_DTPREL_HI16", /* name */
1401 FALSE
, /* partial_inplace */
1402 0x0000ffff, /* src_mask */
1403 0x0000ffff, /* dst_mask */
1404 FALSE
), /* pcrel_offset */
1406 /* TLS local dynamic offset. */
1407 HOWTO (R_MIPS_TLS_DTPREL_LO16
, /* type */
1409 2, /* size (0 = byte, 1 = short, 2 = long) */
1411 FALSE
, /* pc_relative */
1413 complain_overflow_signed
, /* complain_on_overflow */
1414 _bfd_mips_elf_generic_reloc
, /* special_function */
1415 "R_MIPS_TLS_DTPREL_LO16", /* name */
1416 FALSE
, /* partial_inplace */
1417 0x0000ffff, /* src_mask */
1418 0x0000ffff, /* dst_mask */
1419 FALSE
), /* pcrel_offset */
1421 /* TLS thread pointer offset. */
1422 HOWTO (R_MIPS_TLS_GOTTPREL
, /* type */
1424 2, /* size (0 = byte, 1 = short, 2 = long) */
1426 FALSE
, /* pc_relative */
1428 complain_overflow_signed
, /* complain_on_overflow */
1429 _bfd_mips_elf_generic_reloc
, /* special_function */
1430 "R_MIPS_TLS_GOTTPREL", /* name */
1431 FALSE
, /* partial_inplace */
1432 0x0000ffff, /* src_mask */
1433 0x0000ffff, /* dst_mask */
1434 FALSE
), /* pcrel_offset */
1436 /* TLS IE dynamic relocations. */
1437 EMPTY_HOWTO (R_MIPS_TLS_TPREL32
),
1439 HOWTO (R_MIPS_TLS_TPREL64
, /* type */
1441 4, /* size (0 = byte, 1 = short, 2 = long) */
1443 FALSE
, /* pc_relative */
1445 complain_overflow_dont
, /* complain_on_overflow */
1446 _bfd_mips_elf_generic_reloc
, /* special_function */
1447 "R_MIPS_TLS_TPREL64", /* name */
1448 FALSE
, /* partial_inplace */
1449 MINUS_ONE
, /* src_mask */
1450 MINUS_ONE
, /* dst_mask */
1451 FALSE
), /* pcrel_offset */
1453 /* TLS thread pointer offset. */
1454 HOWTO (R_MIPS_TLS_TPREL_HI16
, /* type */
1456 2, /* size (0 = byte, 1 = short, 2 = long) */
1458 FALSE
, /* pc_relative */
1460 complain_overflow_signed
, /* complain_on_overflow */
1461 _bfd_mips_elf_generic_reloc
, /* special_function */
1462 "R_MIPS_TLS_TPREL_HI16", /* name */
1463 FALSE
, /* partial_inplace */
1464 0x0000ffff, /* src_mask */
1465 0x0000ffff, /* dst_mask */
1466 FALSE
), /* pcrel_offset */
1468 /* TLS thread pointer offset. */
1469 HOWTO (R_MIPS_TLS_TPREL_LO16
, /* type */
1471 2, /* size (0 = byte, 1 = short, 2 = long) */
1473 FALSE
, /* pc_relative */
1475 complain_overflow_signed
, /* complain_on_overflow */
1476 _bfd_mips_elf_generic_reloc
, /* special_function */
1477 "R_MIPS_TLS_TPREL_LO16", /* name */
1478 FALSE
, /* partial_inplace */
1479 0x0000ffff, /* src_mask */
1480 0x0000ffff, /* dst_mask */
1481 FALSE
), /* pcrel_offset */
1483 /* 32 bit relocation with no addend. */
1484 HOWTO (R_MIPS_GLOB_DAT
, /* type */
1486 2, /* size (0 = byte, 1 = short, 2 = long) */
1488 FALSE
, /* pc_relative */
1490 complain_overflow_dont
, /* complain_on_overflow */
1491 _bfd_mips_elf_generic_reloc
, /* special_function */
1492 "R_MIPS_GLOB_DAT", /* name */
1493 FALSE
, /* partial_inplace */
1495 0xffffffff, /* dst_mask */
1496 FALSE
), /* pcrel_offset */
1499 static reloc_howto_type mips16_elf64_howto_table_rel
[] =
1501 /* The reloc used for the mips16 jump instruction. */
1502 HOWTO (R_MIPS16_26
, /* type */
1504 2, /* size (0 = byte, 1 = short, 2 = long) */
1506 FALSE
, /* pc_relative */
1508 complain_overflow_dont
, /* complain_on_overflow */
1509 /* This needs complex overflow
1510 detection, because the upper four
1511 bits must match the PC. */
1512 _bfd_mips_elf_generic_reloc
, /* special_function */
1513 "R_MIPS16_26", /* name */
1514 TRUE
, /* partial_inplace */
1515 0x3ffffff, /* src_mask */
1516 0x3ffffff, /* dst_mask */
1517 FALSE
), /* pcrel_offset */
1519 /* The reloc used for the mips16 gprel instruction. */
1520 HOWTO (R_MIPS16_GPREL
, /* type */
1522 2, /* size (0 = byte, 1 = short, 2 = long) */
1524 FALSE
, /* pc_relative */
1526 complain_overflow_signed
, /* complain_on_overflow */
1527 mips16_gprel_reloc
, /* special_function */
1528 "R_MIPS16_GPREL", /* name */
1529 TRUE
, /* partial_inplace */
1530 0x0000ffff, /* src_mask */
1531 0x0000ffff, /* dst_mask */
1532 FALSE
), /* pcrel_offset */
1534 /* A MIPS16 reference to the global offset table. */
1535 HOWTO (R_MIPS16_GOT16
, /* type */
1537 2, /* size (0 = byte, 1 = short, 2 = long) */
1539 FALSE
, /* pc_relative */
1541 complain_overflow_dont
, /* complain_on_overflow */
1542 _bfd_mips_elf_got16_reloc
, /* special_function */
1543 "R_MIPS16_GOT16", /* name */
1544 TRUE
, /* partial_inplace */
1545 0x0000ffff, /* src_mask */
1546 0x0000ffff, /* dst_mask */
1547 FALSE
), /* pcrel_offset */
1549 /* A MIPS16 call through the global offset table. */
1550 HOWTO (R_MIPS16_CALL16
, /* type */
1552 2, /* size (0 = byte, 1 = short, 2 = long) */
1554 FALSE
, /* pc_relative */
1556 complain_overflow_dont
, /* complain_on_overflow */
1557 _bfd_mips_elf_generic_reloc
, /* special_function */
1558 "R_MIPS16_CALL16", /* name */
1559 TRUE
, /* partial_inplace */
1560 0x0000ffff, /* src_mask */
1561 0x0000ffff, /* dst_mask */
1562 FALSE
), /* pcrel_offset */
1564 /* MIPS16 high 16 bits of symbol value. */
1565 HOWTO (R_MIPS16_HI16
, /* type */
1566 16, /* rightshift */
1567 2, /* size (0 = byte, 1 = short, 2 = long) */
1569 FALSE
, /* pc_relative */
1571 complain_overflow_dont
, /* complain_on_overflow */
1572 _bfd_mips_elf_hi16_reloc
, /* special_function */
1573 "R_MIPS16_HI16", /* name */
1574 TRUE
, /* partial_inplace */
1575 0x0000ffff, /* src_mask */
1576 0x0000ffff, /* dst_mask */
1577 FALSE
), /* pcrel_offset */
1579 /* MIPS16 low 16 bits of symbol value. */
1580 HOWTO (R_MIPS16_LO16
, /* type */
1582 2, /* size (0 = byte, 1 = short, 2 = long) */
1584 FALSE
, /* pc_relative */
1586 complain_overflow_dont
, /* complain_on_overflow */
1587 _bfd_mips_elf_lo16_reloc
, /* special_function */
1588 "R_MIPS16_LO16", /* name */
1589 TRUE
, /* partial_inplace */
1590 0x0000ffff, /* src_mask */
1591 0x0000ffff, /* dst_mask */
1592 FALSE
), /* pcrel_offset */
1595 static reloc_howto_type mips16_elf64_howto_table_rela
[] =
1597 /* The reloc used for the mips16 jump instruction. */
1598 HOWTO (R_MIPS16_26
, /* type */
1600 2, /* size (0 = byte, 1 = short, 2 = long) */
1602 FALSE
, /* pc_relative */
1604 complain_overflow_dont
, /* complain_on_overflow */
1605 /* This needs complex overflow
1606 detection, because the upper four
1607 bits must match the PC. */
1608 _bfd_mips_elf_generic_reloc
, /* special_function */
1609 "R_MIPS16_26", /* name */
1610 FALSE
, /* partial_inplace */
1611 0x3ffffff, /* src_mask */
1612 0x3ffffff, /* dst_mask */
1613 FALSE
), /* pcrel_offset */
1615 /* The reloc used for the mips16 gprel instruction. */
1616 HOWTO (R_MIPS16_GPREL
, /* type */
1618 2, /* size (0 = byte, 1 = short, 2 = long) */
1620 FALSE
, /* pc_relative */
1622 complain_overflow_signed
, /* complain_on_overflow */
1623 mips16_gprel_reloc
, /* special_function */
1624 "R_MIPS16_GPREL", /* name */
1625 FALSE
, /* partial_inplace */
1626 0x0000ffff, /* src_mask */
1627 0x0000ffff, /* dst_mask */
1628 FALSE
), /* pcrel_offset */
1630 /* A MIPS16 reference to the global offset table. */
1631 HOWTO (R_MIPS16_GOT16
, /* type */
1633 2, /* size (0 = byte, 1 = short, 2 = long) */
1635 FALSE
, /* pc_relative */
1637 complain_overflow_dont
, /* complain_on_overflow */
1638 _bfd_mips_elf_got16_reloc
, /* special_function */
1639 "R_MIPS16_GOT16", /* name */
1640 FALSE
, /* partial_inplace */
1641 0x0000ffff, /* src_mask */
1642 0x0000ffff, /* dst_mask */
1643 FALSE
), /* pcrel_offset */
1645 /* A MIPS16 call through the global offset table. */
1646 HOWTO (R_MIPS16_CALL16
, /* type */
1648 2, /* size (0 = byte, 1 = short, 2 = long) */
1650 FALSE
, /* pc_relative */
1652 complain_overflow_dont
, /* complain_on_overflow */
1653 _bfd_mips_elf_generic_reloc
, /* special_function */
1654 "R_MIPS16_CALL16", /* name */
1655 FALSE
, /* partial_inplace */
1656 0x0000ffff, /* src_mask */
1657 0x0000ffff, /* dst_mask */
1658 FALSE
), /* pcrel_offset */
1660 /* MIPS16 high 16 bits of symbol value. */
1661 HOWTO (R_MIPS16_HI16
, /* type */
1662 16, /* rightshift */
1663 2, /* size (0 = byte, 1 = short, 2 = long) */
1665 FALSE
, /* pc_relative */
1667 complain_overflow_dont
, /* complain_on_overflow */
1668 _bfd_mips_elf_hi16_reloc
, /* special_function */
1669 "R_MIPS16_HI16", /* name */
1670 FALSE
, /* partial_inplace */
1671 0x0000ffff, /* src_mask */
1672 0x0000ffff, /* dst_mask */
1673 FALSE
), /* pcrel_offset */
1675 /* MIPS16 low 16 bits of symbol value. */
1676 HOWTO (R_MIPS16_LO16
, /* type */
1678 2, /* size (0 = byte, 1 = short, 2 = long) */
1680 FALSE
, /* pc_relative */
1682 complain_overflow_dont
, /* complain_on_overflow */
1683 _bfd_mips_elf_lo16_reloc
, /* special_function */
1684 "R_MIPS16_LO16", /* name */
1685 FALSE
, /* partial_inplace */
1686 0x0000ffff, /* src_mask */
1687 0x0000ffff, /* dst_mask */
1688 FALSE
), /* pcrel_offset */
1691 /* GNU extension to record C++ vtable hierarchy */
1692 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
1693 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
1695 2, /* size (0 = byte, 1 = short, 2 = long) */
1697 FALSE
, /* pc_relative */
1699 complain_overflow_dont
, /* complain_on_overflow */
1700 NULL
, /* special_function */
1701 "R_MIPS_GNU_VTINHERIT", /* name */
1702 FALSE
, /* partial_inplace */
1705 FALSE
); /* pcrel_offset */
1707 /* GNU extension to record C++ vtable member usage */
1708 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
1709 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
1711 2, /* size (0 = byte, 1 = short, 2 = long) */
1713 FALSE
, /* pc_relative */
1715 complain_overflow_dont
, /* complain_on_overflow */
1716 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
1717 "R_MIPS_GNU_VTENTRY", /* name */
1718 FALSE
, /* partial_inplace */
1721 FALSE
); /* pcrel_offset */
1723 /* 16 bit offset for pc-relative branches. */
1724 static reloc_howto_type elf_mips_gnu_rel16_s2
=
1725 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1727 2, /* size (0 = byte, 1 = short, 2 = long) */
1729 TRUE
, /* pc_relative */
1731 complain_overflow_signed
, /* complain_on_overflow */
1732 _bfd_mips_elf_generic_reloc
, /* special_function */
1733 "R_MIPS_GNU_REL16_S2", /* name */
1734 TRUE
, /* partial_inplace */
1735 0x0000ffff, /* src_mask */
1736 0x0000ffff, /* dst_mask */
1737 TRUE
); /* pcrel_offset */
1739 /* 16 bit offset for pc-relative branches. */
1740 static reloc_howto_type elf_mips_gnu_rela16_s2
=
1741 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1743 2, /* size (0 = byte, 1 = short, 2 = long) */
1745 TRUE
, /* pc_relative */
1747 complain_overflow_signed
, /* complain_on_overflow */
1748 _bfd_mips_elf_generic_reloc
, /* special_function */
1749 "R_MIPS_GNU_REL16_S2", /* name */
1750 FALSE
, /* partial_inplace */
1752 0x0000ffff, /* dst_mask */
1753 TRUE
); /* pcrel_offset */
1755 /* Originally a VxWorks extension, but now used for other systems too. */
1756 static reloc_howto_type elf_mips_copy_howto
=
1757 HOWTO (R_MIPS_COPY
, /* type */
1759 0, /* this one is variable size */
1761 FALSE
, /* pc_relative */
1763 complain_overflow_bitfield
, /* complain_on_overflow */
1764 bfd_elf_generic_reloc
, /* special_function */
1765 "R_MIPS_COPY", /* name */
1766 FALSE
, /* partial_inplace */
1769 FALSE
); /* pcrel_offset */
1771 /* Originally a VxWorks extension, but now used for other systems too. */
1772 static reloc_howto_type elf_mips_jump_slot_howto
=
1773 HOWTO (R_MIPS_JUMP_SLOT
, /* type */
1775 4, /* size (0 = byte, 1 = short, 2 = long) */
1777 FALSE
, /* pc_relative */
1779 complain_overflow_bitfield
, /* complain_on_overflow */
1780 bfd_elf_generic_reloc
, /* special_function */
1781 "R_MIPS_JUMP_SLOT", /* name */
1782 FALSE
, /* partial_inplace */
1785 FALSE
); /* pcrel_offset */
1787 /* Swap in a MIPS 64-bit Rel reloc. */
1790 mips_elf64_swap_reloc_in (bfd
*abfd
, const Elf64_Mips_External_Rel
*src
,
1791 Elf64_Mips_Internal_Rela
*dst
)
1793 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1794 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1795 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1796 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1797 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1798 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1802 /* Swap in a MIPS 64-bit Rela reloc. */
1805 mips_elf64_swap_reloca_in (bfd
*abfd
, const Elf64_Mips_External_Rela
*src
,
1806 Elf64_Mips_Internal_Rela
*dst
)
1808 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1809 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1810 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1811 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1812 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1813 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1814 dst
->r_addend
= H_GET_S64 (abfd
, src
->r_addend
);
1817 /* Swap out a MIPS 64-bit Rel reloc. */
1820 mips_elf64_swap_reloc_out (bfd
*abfd
, const Elf64_Mips_Internal_Rela
*src
,
1821 Elf64_Mips_External_Rel
*dst
)
1823 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1824 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1825 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1826 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1827 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1828 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1831 /* Swap out a MIPS 64-bit Rela reloc. */
1834 mips_elf64_swap_reloca_out (bfd
*abfd
, const Elf64_Mips_Internal_Rela
*src
,
1835 Elf64_Mips_External_Rela
*dst
)
1837 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1838 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1839 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1840 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1841 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1842 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1843 H_PUT_S64 (abfd
, src
->r_addend
, dst
->r_addend
);
1846 /* Swap in a MIPS 64-bit Rel reloc. */
1849 mips_elf64_be_swap_reloc_in (bfd
*abfd
, const bfd_byte
*src
,
1850 Elf_Internal_Rela
*dst
)
1852 Elf64_Mips_Internal_Rela mirel
;
1854 mips_elf64_swap_reloc_in (abfd
,
1855 (const Elf64_Mips_External_Rel
*) src
,
1858 dst
[0].r_offset
= mirel
.r_offset
;
1859 dst
[0].r_info
= ELF64_R_INFO (mirel
.r_sym
, mirel
.r_type
);
1860 dst
[0].r_addend
= 0;
1861 dst
[1].r_offset
= mirel
.r_offset
;
1862 dst
[1].r_info
= ELF64_R_INFO (mirel
.r_ssym
, mirel
.r_type2
);
1863 dst
[1].r_addend
= 0;
1864 dst
[2].r_offset
= mirel
.r_offset
;
1865 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirel
.r_type3
);
1866 dst
[2].r_addend
= 0;
1869 /* Swap in a MIPS 64-bit Rela reloc. */
1872 mips_elf64_be_swap_reloca_in (bfd
*abfd
, const bfd_byte
*src
,
1873 Elf_Internal_Rela
*dst
)
1875 Elf64_Mips_Internal_Rela mirela
;
1877 mips_elf64_swap_reloca_in (abfd
,
1878 (const Elf64_Mips_External_Rela
*) src
,
1881 dst
[0].r_offset
= mirela
.r_offset
;
1882 dst
[0].r_info
= ELF64_R_INFO (mirela
.r_sym
, mirela
.r_type
);
1883 dst
[0].r_addend
= mirela
.r_addend
;
1884 dst
[1].r_offset
= mirela
.r_offset
;
1885 dst
[1].r_info
= ELF64_R_INFO (mirela
.r_ssym
, mirela
.r_type2
);
1886 dst
[1].r_addend
= 0;
1887 dst
[2].r_offset
= mirela
.r_offset
;
1888 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirela
.r_type3
);
1889 dst
[2].r_addend
= 0;
1892 /* Swap out a MIPS 64-bit Rel reloc. */
1895 mips_elf64_be_swap_reloc_out (bfd
*abfd
, const Elf_Internal_Rela
*src
,
1898 Elf64_Mips_Internal_Rela mirel
;
1900 mirel
.r_offset
= src
[0].r_offset
;
1901 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1903 mirel
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1904 mirel
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1905 mirel
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1906 mirel
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1907 mirel
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1909 mips_elf64_swap_reloc_out (abfd
, &mirel
,
1910 (Elf64_Mips_External_Rel
*) dst
);
1913 /* Swap out a MIPS 64-bit Rela reloc. */
1916 mips_elf64_be_swap_reloca_out (bfd
*abfd
, const Elf_Internal_Rela
*src
,
1919 Elf64_Mips_Internal_Rela mirela
;
1921 mirela
.r_offset
= src
[0].r_offset
;
1922 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1923 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1925 mirela
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1926 mirela
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1927 mirela
.r_addend
= src
[0].r_addend
;
1928 BFD_ASSERT(src
[1].r_addend
== 0);
1929 BFD_ASSERT(src
[2].r_addend
== 0);
1931 mirela
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1932 mirela
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1933 mirela
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1935 mips_elf64_swap_reloca_out (abfd
, &mirela
,
1936 (Elf64_Mips_External_Rela
*) dst
);
1939 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1940 dangerous relocation. */
1943 mips_elf64_assign_gp (bfd
*output_bfd
, bfd_vma
*pgp
)
1949 /* If we've already figured out what GP will be, just return it. */
1950 *pgp
= _bfd_get_gp_value (output_bfd
);
1954 count
= bfd_get_symcount (output_bfd
);
1955 sym
= bfd_get_outsymbols (output_bfd
);
1957 /* The linker script will have created a symbol named `_gp' with the
1958 appropriate value. */
1963 for (i
= 0; i
< count
; i
++, sym
++)
1965 register const char *name
;
1967 name
= bfd_asymbol_name (*sym
);
1968 if (*name
== '_' && strcmp (name
, "_gp") == 0)
1970 *pgp
= bfd_asymbol_value (*sym
);
1971 _bfd_set_gp_value (output_bfd
, *pgp
);
1979 /* Only get the error once. */
1981 _bfd_set_gp_value (output_bfd
, *pgp
);
1988 /* We have to figure out the gp value, so that we can adjust the
1989 symbol value correctly. We look up the symbol _gp in the output
1990 BFD. If we can't find it, we're stuck. We cache it in the ELF
1991 target data. We don't need to adjust the symbol value for an
1992 external symbol if we are producing relocatable output. */
1994 static bfd_reloc_status_type
1995 mips_elf64_final_gp (bfd
*output_bfd
, asymbol
*symbol
, bfd_boolean relocatable
,
1996 char **error_message
, bfd_vma
*pgp
)
1998 if (bfd_is_und_section (symbol
->section
)
2002 return bfd_reloc_undefined
;
2005 *pgp
= _bfd_get_gp_value (output_bfd
);
2008 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
2012 /* Make up a value. */
2013 *pgp
= symbol
->section
->output_section
->vma
/*+ 0x4000*/;
2014 _bfd_set_gp_value (output_bfd
, *pgp
);
2016 else if (!mips_elf64_assign_gp (output_bfd
, pgp
))
2019 (char *) _("GP relative relocation when _gp not defined");
2020 return bfd_reloc_dangerous
;
2024 return bfd_reloc_ok
;
2027 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
2028 become the offset from the gp register. */
2030 static bfd_reloc_status_type
2031 mips_elf64_gprel16_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
2032 void *data
, asection
*input_section
, bfd
*output_bfd
,
2033 char **error_message
)
2035 bfd_boolean relocatable
;
2036 bfd_reloc_status_type ret
;
2039 /* If we're relocating, and this is an external symbol, we don't want
2040 to change anything. */
2041 if (output_bfd
!= NULL
2042 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
2043 && (symbol
->flags
& BSF_LOCAL
) != 0)
2045 reloc_entry
->address
+= input_section
->output_offset
;
2046 return bfd_reloc_ok
;
2049 if (output_bfd
!= NULL
)
2053 relocatable
= FALSE
;
2054 output_bfd
= symbol
->section
->output_section
->owner
;
2057 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
2059 if (ret
!= bfd_reloc_ok
)
2062 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
2063 input_section
, relocatable
,
2067 /* Do a R_MIPS_LITERAL relocation. */
2069 static bfd_reloc_status_type
2070 mips_elf64_literal_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
2071 void *data
, asection
*input_section
, bfd
*output_bfd
,
2072 char **error_message
)
2074 bfd_boolean relocatable
;
2075 bfd_reloc_status_type ret
;
2078 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
2079 if (output_bfd
!= NULL
2080 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
2081 && (symbol
->flags
& BSF_LOCAL
) != 0)
2083 *error_message
= (char *)
2084 _("literal relocation occurs for an external symbol");
2085 return bfd_reloc_outofrange
;
2088 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
2089 if (output_bfd
!= NULL
)
2093 relocatable
= FALSE
;
2094 output_bfd
= symbol
->section
->output_section
->owner
;
2097 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
2099 if (ret
!= bfd_reloc_ok
)
2102 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
2103 input_section
, relocatable
,
2107 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
2108 become the offset from the gp register. */
2110 static bfd_reloc_status_type
2111 mips_elf64_gprel32_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
2112 void *data
, asection
*input_section
, bfd
*output_bfd
,
2113 char **error_message
)
2115 bfd_boolean relocatable
;
2116 bfd_reloc_status_type ret
;
2121 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
2122 if (output_bfd
!= NULL
2123 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
2124 && (symbol
->flags
& BSF_LOCAL
) != 0)
2126 *error_message
= (char *)
2127 _("32bits gp relative relocation occurs for an external symbol");
2128 return bfd_reloc_outofrange
;
2131 if (output_bfd
!= NULL
)
2135 relocatable
= FALSE
;
2136 output_bfd
= symbol
->section
->output_section
->owner
;
2139 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
,
2140 error_message
, &gp
);
2141 if (ret
!= bfd_reloc_ok
)
2144 if (bfd_is_com_section (symbol
->section
))
2147 relocation
= symbol
->value
;
2149 relocation
+= symbol
->section
->output_section
->vma
;
2150 relocation
+= symbol
->section
->output_offset
;
2152 if (reloc_entry
->address
> bfd_get_section_limit (abfd
, input_section
))
2153 return bfd_reloc_outofrange
;
2155 /* Set val to the offset into the section or symbol. */
2156 val
= reloc_entry
->addend
;
2158 if (reloc_entry
->howto
->partial_inplace
)
2159 val
+= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
2161 /* Adjust val for the final section location and GP value. If we
2162 are producing relocatable output, we don't want to do this for
2163 an external symbol. */
2165 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
2166 val
+= relocation
- gp
;
2168 if (reloc_entry
->howto
->partial_inplace
)
2169 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
2171 reloc_entry
->addend
= val
;
2174 reloc_entry
->address
+= input_section
->output_offset
;
2176 return bfd_reloc_ok
;
2179 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2180 the rest is at bits 6-10. The bitpos already got right by the howto. */
2182 static bfd_reloc_status_type
2183 mips_elf64_shift6_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
2184 void *data
, asection
*input_section
, bfd
*output_bfd
,
2185 char **error_message
)
2187 if (reloc_entry
->howto
->partial_inplace
)
2189 reloc_entry
->addend
= ((reloc_entry
->addend
& 0x00007c0)
2190 | (reloc_entry
->addend
& 0x00000800) >> 9);
2193 return _bfd_mips_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
2194 input_section
, output_bfd
,
2198 /* Handle a mips16 GP relative reloc. */
2200 static bfd_reloc_status_type
2201 mips16_gprel_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
2202 void *data
, asection
*input_section
, bfd
*output_bfd
,
2203 char **error_message
)
2205 bfd_boolean relocatable
;
2206 bfd_reloc_status_type ret
;
2210 /* If we're relocating, and this is an external symbol, we don't want
2211 to change anything. */
2212 if (output_bfd
!= NULL
2213 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
2214 && (symbol
->flags
& BSF_LOCAL
) != 0)
2216 reloc_entry
->address
+= input_section
->output_offset
;
2217 return bfd_reloc_ok
;
2220 if (output_bfd
!= NULL
)
2224 relocatable
= FALSE
;
2225 output_bfd
= symbol
->section
->output_section
->owner
;
2228 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
2230 if (ret
!= bfd_reloc_ok
)
2233 location
= (bfd_byte
*) data
+ reloc_entry
->address
;
2234 _bfd_mips16_elf_reloc_unshuffle (abfd
, reloc_entry
->howto
->type
, FALSE
,
2236 ret
= _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
2237 input_section
, relocatable
,
2239 _bfd_mips16_elf_reloc_shuffle (abfd
, reloc_entry
->howto
->type
, !relocatable
,
2245 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2247 struct elf_reloc_map
{
2248 bfd_reloc_code_real_type bfd_val
;
2249 enum elf_mips_reloc_type elf_val
;
2252 static const struct elf_reloc_map mips_reloc_map
[] =
2254 { BFD_RELOC_NONE
, R_MIPS_NONE
},
2255 { BFD_RELOC_16
, R_MIPS_16
},
2256 { BFD_RELOC_32
, R_MIPS_32
},
2257 /* There is no BFD reloc for R_MIPS_REL32. */
2258 { BFD_RELOC_64
, R_MIPS_64
},
2259 { BFD_RELOC_CTOR
, R_MIPS_64
},
2260 { BFD_RELOC_16_PCREL_S2
, R_MIPS_PC16
},
2261 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
2262 { BFD_RELOC_LO16
, R_MIPS_LO16
},
2263 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
2264 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
2265 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
2266 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
2267 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
2268 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
2269 { BFD_RELOC_MIPS_SHIFT5
, R_MIPS_SHIFT5
},
2270 { BFD_RELOC_MIPS_SHIFT6
, R_MIPS_SHIFT6
},
2271 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
},
2272 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
2273 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
2274 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
2275 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
2276 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
2277 { BFD_RELOC_MIPS_INSERT_A
, R_MIPS_INSERT_A
},
2278 { BFD_RELOC_MIPS_INSERT_B
, R_MIPS_INSERT_B
},
2279 { BFD_RELOC_MIPS_DELETE
, R_MIPS_DELETE
},
2280 { BFD_RELOC_MIPS_HIGHEST
, R_MIPS_HIGHEST
},
2281 { BFD_RELOC_MIPS_HIGHER
, R_MIPS_HIGHER
},
2282 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
2283 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
2284 { BFD_RELOC_MIPS_SCN_DISP
, R_MIPS_SCN_DISP
},
2285 { BFD_RELOC_MIPS_REL16
, R_MIPS_REL16
},
2286 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2287 { BFD_RELOC_MIPS_RELGOT
, R_MIPS_RELGOT
},
2288 { BFD_RELOC_MIPS_JALR
, R_MIPS_JALR
},
2289 { BFD_RELOC_MIPS_TLS_DTPMOD32
, R_MIPS_TLS_DTPMOD32
},
2290 { BFD_RELOC_MIPS_TLS_DTPREL32
, R_MIPS_TLS_DTPREL32
},
2291 { BFD_RELOC_MIPS_TLS_DTPMOD64
, R_MIPS_TLS_DTPMOD64
},
2292 { BFD_RELOC_MIPS_TLS_DTPREL64
, R_MIPS_TLS_DTPREL64
},
2293 { BFD_RELOC_MIPS_TLS_GD
, R_MIPS_TLS_GD
},
2294 { BFD_RELOC_MIPS_TLS_LDM
, R_MIPS_TLS_LDM
},
2295 { BFD_RELOC_MIPS_TLS_DTPREL_HI16
, R_MIPS_TLS_DTPREL_HI16
},
2296 { BFD_RELOC_MIPS_TLS_DTPREL_LO16
, R_MIPS_TLS_DTPREL_LO16
},
2297 { BFD_RELOC_MIPS_TLS_GOTTPREL
, R_MIPS_TLS_GOTTPREL
},
2298 { BFD_RELOC_MIPS_TLS_TPREL32
, R_MIPS_TLS_TPREL32
},
2299 { BFD_RELOC_MIPS_TLS_TPREL64
, R_MIPS_TLS_TPREL64
},
2300 { BFD_RELOC_MIPS_TLS_TPREL_HI16
, R_MIPS_TLS_TPREL_HI16
},
2301 { BFD_RELOC_MIPS_TLS_TPREL_LO16
, R_MIPS_TLS_TPREL_LO16
}
2304 static const struct elf_reloc_map mips16_reloc_map
[] =
2306 { BFD_RELOC_MIPS16_JMP
, R_MIPS16_26
- R_MIPS16_min
},
2307 { BFD_RELOC_MIPS16_GPREL
, R_MIPS16_GPREL
- R_MIPS16_min
},
2308 { BFD_RELOC_MIPS16_GOT16
, R_MIPS16_GOT16
- R_MIPS16_min
},
2309 { BFD_RELOC_MIPS16_CALL16
, R_MIPS16_CALL16
- R_MIPS16_min
},
2310 { BFD_RELOC_MIPS16_HI16_S
, R_MIPS16_HI16
- R_MIPS16_min
},
2311 { BFD_RELOC_MIPS16_LO16
, R_MIPS16_LO16
- R_MIPS16_min
},
2314 /* Given a BFD reloc type, return a howto structure. */
2316 static reloc_howto_type
*
2317 bfd_elf64_bfd_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
2318 bfd_reloc_code_real_type code
)
2321 /* FIXME: We default to RELA here instead of choosing the right
2322 relocation variant. */
2323 reloc_howto_type
*howto_table
= mips_elf64_howto_table_rela
;
2324 reloc_howto_type
*howto16_table
= mips16_elf64_howto_table_rela
;
2326 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
2329 if (mips_reloc_map
[i
].bfd_val
== code
)
2330 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
2333 for (i
= 0; i
< sizeof (mips16_reloc_map
) / sizeof (struct elf_reloc_map
);
2336 if (mips16_reloc_map
[i
].bfd_val
== code
)
2337 return &howto16_table
[(int) mips16_reloc_map
[i
].elf_val
];
2342 case BFD_RELOC_VTABLE_INHERIT
:
2343 return &elf_mips_gnu_vtinherit_howto
;
2344 case BFD_RELOC_VTABLE_ENTRY
:
2345 return &elf_mips_gnu_vtentry_howto
;
2346 case BFD_RELOC_MIPS_COPY
:
2347 return &elf_mips_copy_howto
;
2348 case BFD_RELOC_MIPS_JUMP_SLOT
:
2349 return &elf_mips_jump_slot_howto
;
2351 bfd_set_error (bfd_error_bad_value
);
2356 static reloc_howto_type
*
2357 bfd_elf64_bfd_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
2363 i
< (sizeof (mips_elf64_howto_table_rela
)
2364 / sizeof (mips_elf64_howto_table_rela
[0])); i
++)
2365 if (mips_elf64_howto_table_rela
[i
].name
!= NULL
2366 && strcasecmp (mips_elf64_howto_table_rela
[i
].name
, r_name
) == 0)
2367 return &mips_elf64_howto_table_rela
[i
];
2370 i
< (sizeof (mips16_elf64_howto_table_rela
)
2371 / sizeof (mips16_elf64_howto_table_rela
[0]));
2373 if (mips16_elf64_howto_table_rela
[i
].name
!= NULL
2374 && strcasecmp (mips16_elf64_howto_table_rela
[i
].name
, r_name
) == 0)
2375 return &mips16_elf64_howto_table_rela
[i
];
2377 if (strcasecmp (elf_mips_gnu_vtinherit_howto
.name
, r_name
) == 0)
2378 return &elf_mips_gnu_vtinherit_howto
;
2379 if (strcasecmp (elf_mips_gnu_vtentry_howto
.name
, r_name
) == 0)
2380 return &elf_mips_gnu_vtentry_howto
;
2381 if (strcasecmp (elf_mips_gnu_rel16_s2
.name
, r_name
) == 0)
2382 return &elf_mips_gnu_rel16_s2
;
2383 if (strcasecmp (elf_mips_gnu_rela16_s2
.name
, r_name
) == 0)
2384 return &elf_mips_gnu_rela16_s2
;
2385 if (strcasecmp (elf_mips_copy_howto
.name
, r_name
) == 0)
2386 return &elf_mips_copy_howto
;
2387 if (strcasecmp (elf_mips_jump_slot_howto
.name
, r_name
) == 0)
2388 return &elf_mips_jump_slot_howto
;
2393 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2395 static reloc_howto_type
*
2396 mips_elf64_rtype_to_howto (unsigned int r_type
, bfd_boolean rela_p
)
2400 case R_MIPS_GNU_VTINHERIT
:
2401 return &elf_mips_gnu_vtinherit_howto
;
2402 case R_MIPS_GNU_VTENTRY
:
2403 return &elf_mips_gnu_vtentry_howto
;
2404 case R_MIPS_GNU_REL16_S2
:
2406 return &elf_mips_gnu_rela16_s2
;
2408 return &elf_mips_gnu_rel16_s2
;
2410 return &elf_mips_copy_howto
;
2411 case R_MIPS_JUMP_SLOT
:
2412 return &elf_mips_jump_slot_howto
;
2414 if (r_type
>= R_MIPS16_min
&& r_type
< R_MIPS16_max
)
2417 return &mips16_elf64_howto_table_rela
[r_type
- R_MIPS16_min
];
2419 return &mips16_elf64_howto_table_rel
[r_type
- R_MIPS16_min
];
2421 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
2423 return &mips_elf64_howto_table_rela
[r_type
];
2425 return &mips_elf64_howto_table_rel
[r_type
];
2430 /* Prevent relocation handling by bfd for MIPS ELF64. */
2433 mips_elf64_info_to_howto_rel (bfd
*abfd ATTRIBUTE_UNUSED
,
2434 arelent
*cache_ptr ATTRIBUTE_UNUSED
,
2435 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
)
2441 mips_elf64_info_to_howto_rela (bfd
*abfd ATTRIBUTE_UNUSED
,
2442 arelent
*cache_ptr ATTRIBUTE_UNUSED
,
2443 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
)
2448 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2449 to three relocs, we must tell the user to allocate more space. */
2452 mips_elf64_get_reloc_upper_bound (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
)
2454 return (sec
->reloc_count
* 3 + 1) * sizeof (arelent
*);
2458 mips_elf64_get_dynamic_reloc_upper_bound (bfd
*abfd
)
2460 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd
) * 3;
2463 /* We must also copy more relocations than the corresponding functions
2464 in elf.c would, so the two following functions are slightly
2465 modified from elf.c, that multiply the external relocation count by
2466 3 to obtain the internal relocation count. */
2469 mips_elf64_canonicalize_reloc (bfd
*abfd
, sec_ptr section
,
2470 arelent
**relptr
, asymbol
**symbols
)
2474 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
2476 if (! bed
->s
->slurp_reloc_table (abfd
, section
, symbols
, FALSE
))
2479 tblptr
= section
->relocation
;
2480 for (i
= 0; i
< section
->reloc_count
* 3; i
++)
2481 *relptr
++ = tblptr
++;
2485 return section
->reloc_count
* 3;
2489 mips_elf64_canonicalize_dynamic_reloc (bfd
*abfd
, arelent
**storage
,
2492 bfd_boolean (*slurp_relocs
) (bfd
*, asection
*, asymbol
**, bfd_boolean
);
2496 if (elf_dynsymtab (abfd
) == 0)
2498 bfd_set_error (bfd_error_invalid_operation
);
2502 slurp_relocs
= get_elf_backend_data (abfd
)->s
->slurp_reloc_table
;
2504 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
2506 if (elf_section_data (s
)->this_hdr
.sh_link
== elf_dynsymtab (abfd
)
2507 && (elf_section_data (s
)->this_hdr
.sh_type
== SHT_REL
2508 || elf_section_data (s
)->this_hdr
.sh_type
== SHT_RELA
))
2513 if (! (*slurp_relocs
) (abfd
, s
, syms
, TRUE
))
2515 count
= s
->size
/ elf_section_data (s
)->this_hdr
.sh_entsize
* 3;
2517 for (i
= 0; i
< count
; i
++)
2528 /* Read the relocations from one reloc section. This is mostly copied
2529 from elfcode.h, except for the changes to expand one external
2530 relocation to 3 internal ones. We must unfortunately set
2531 reloc_count to the number of external relocations, because a lot of
2532 generic code seems to depend on this. */
2535 mips_elf64_slurp_one_reloc_table (bfd
*abfd
, asection
*asect
,
2536 Elf_Internal_Shdr
*rel_hdr
,
2537 bfd_size_type reloc_count
,
2538 arelent
*relents
, asymbol
**symbols
,
2539 bfd_boolean dynamic
)
2542 bfd_byte
*native_relocs
;
2548 allocated
= bfd_malloc (rel_hdr
->sh_size
);
2549 if (allocated
== NULL
)
2552 if (bfd_seek (abfd
, rel_hdr
->sh_offset
, SEEK_SET
) != 0
2553 || (bfd_bread (allocated
, rel_hdr
->sh_size
, abfd
)
2554 != rel_hdr
->sh_size
))
2557 native_relocs
= allocated
;
2559 entsize
= rel_hdr
->sh_entsize
;
2560 BFD_ASSERT (entsize
== sizeof (Elf64_Mips_External_Rel
)
2561 || entsize
== sizeof (Elf64_Mips_External_Rela
));
2563 if (entsize
== sizeof (Elf64_Mips_External_Rel
))
2568 for (i
= 0, relent
= relents
;
2570 i
++, native_relocs
+= entsize
)
2572 Elf64_Mips_Internal_Rela rela
;
2573 bfd_boolean used_sym
, used_ssym
;
2576 if (entsize
== sizeof (Elf64_Mips_External_Rela
))
2577 mips_elf64_swap_reloca_in (abfd
,
2578 (Elf64_Mips_External_Rela
*) native_relocs
,
2581 mips_elf64_swap_reloc_in (abfd
,
2582 (Elf64_Mips_External_Rel
*) native_relocs
,
2585 /* Each entry represents exactly three actual relocations. */
2589 for (ir
= 0; ir
< 3; ir
++)
2591 enum elf_mips_reloc_type type
;
2598 type
= (enum elf_mips_reloc_type
) rela
.r_type
;
2601 type
= (enum elf_mips_reloc_type
) rela
.r_type2
;
2604 type
= (enum elf_mips_reloc_type
) rela
.r_type3
;
2608 /* Some types require symbols, whereas some do not. */
2612 case R_MIPS_LITERAL
:
2613 case R_MIPS_INSERT_A
:
2614 case R_MIPS_INSERT_B
:
2616 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2622 if (rela
.r_sym
== STN_UNDEF
)
2623 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2628 ps
= symbols
+ rela
.r_sym
- 1;
2630 if ((s
->flags
& BSF_SECTION_SYM
) == 0)
2631 relent
->sym_ptr_ptr
= ps
;
2633 relent
->sym_ptr_ptr
= s
->section
->symbol_ptr_ptr
;
2638 else if (! used_ssym
)
2640 switch (rela
.r_ssym
)
2643 relent
->sym_ptr_ptr
=
2644 bfd_abs_section_ptr
->symbol_ptr_ptr
;
2650 /* FIXME: I think these need to be handled using
2651 special howto structures. */
2663 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2668 /* The address of an ELF reloc is section relative for an
2669 object file, and absolute for an executable file or
2670 shared library. The address of a BFD reloc is always
2671 section relative. */
2672 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0 || dynamic
)
2673 relent
->address
= rela
.r_offset
;
2675 relent
->address
= rela
.r_offset
- asect
->vma
;
2677 relent
->addend
= rela
.r_addend
;
2679 relent
->howto
= mips_elf64_rtype_to_howto (type
, rela_p
);
2685 asect
->reloc_count
+= (relent
- relents
) / 3;
2687 if (allocated
!= NULL
)
2693 if (allocated
!= NULL
)
2698 /* Read the relocations. On Irix 6, there can be two reloc sections
2699 associated with a single data section. This is copied from
2700 elfcode.h as well, with changes as small as accounting for 3
2701 internal relocs per external reloc and resetting reloc_count to
2702 zero before processing the relocs of a section. */
2705 mips_elf64_slurp_reloc_table (bfd
*abfd
, asection
*asect
,
2706 asymbol
**symbols
, bfd_boolean dynamic
)
2708 struct bfd_elf_section_data
* const d
= elf_section_data (asect
);
2709 Elf_Internal_Shdr
*rel_hdr
;
2710 Elf_Internal_Shdr
*rel_hdr2
;
2711 bfd_size_type reloc_count
;
2712 bfd_size_type reloc_count2
;
2716 if (asect
->relocation
!= NULL
)
2721 if ((asect
->flags
& SEC_RELOC
) == 0
2722 || asect
->reloc_count
== 0)
2725 rel_hdr
= d
->rel
.hdr
;
2726 reloc_count
= rel_hdr
? NUM_SHDR_ENTRIES (rel_hdr
) : 0;
2727 rel_hdr2
= d
->rela
.hdr
;
2728 reloc_count2
= (rel_hdr2
? NUM_SHDR_ENTRIES (rel_hdr2
) : 0);
2730 BFD_ASSERT (asect
->reloc_count
== reloc_count
+ reloc_count2
);
2731 BFD_ASSERT ((rel_hdr
&& asect
->rel_filepos
== rel_hdr
->sh_offset
)
2732 || (rel_hdr2
&& asect
->rel_filepos
== rel_hdr2
->sh_offset
));
2737 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2738 case because relocations against this section may use the
2739 dynamic symbol table, and in that case bfd_section_from_shdr
2740 in elf.c does not update the RELOC_COUNT. */
2741 if (asect
->size
== 0)
2744 rel_hdr
= &d
->this_hdr
;
2745 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2750 /* Allocate space for 3 arelent structures for each Rel structure. */
2751 amt
= (reloc_count
+ reloc_count2
) * 3 * sizeof (arelent
);
2752 relents
= bfd_alloc (abfd
, amt
);
2753 if (relents
== NULL
)
2756 /* The slurp_one_reloc_table routine increments reloc_count. */
2757 asect
->reloc_count
= 0;
2760 && ! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2761 rel_hdr
, reloc_count
,
2765 if (rel_hdr2
!= NULL
2766 && ! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2767 rel_hdr2
, reloc_count2
,
2768 relents
+ reloc_count
* 3,
2772 asect
->relocation
= relents
;
2776 /* Write out the relocations. */
2779 mips_elf64_write_relocs (bfd
*abfd
, asection
*sec
, void *data
)
2781 bfd_boolean
*failedp
= data
;
2783 Elf_Internal_Shdr
*rel_hdr
;
2786 /* If we have already failed, don't do anything. */
2790 if ((sec
->flags
& SEC_RELOC
) == 0)
2793 /* The linker backend writes the relocs out itself, and sets the
2794 reloc_count field to zero to inhibit writing them here. Also,
2795 sometimes the SEC_RELOC flag gets set even when there aren't any
2797 if (sec
->reloc_count
== 0)
2800 /* We can combine up to three relocs that refer to the same address
2801 if the latter relocs have no associated symbol. */
2803 for (idx
= 0; idx
< sec
->reloc_count
; idx
++)
2810 addr
= sec
->orelocation
[idx
]->address
;
2811 for (i
= 0; i
< 2; i
++)
2815 if (idx
+ 1 >= sec
->reloc_count
)
2817 r
= sec
->orelocation
[idx
+ 1];
2818 if (r
->address
!= addr
2819 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2820 || (*r
->sym_ptr_ptr
)->value
!= 0)
2823 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2829 rel_hdr
= _bfd_elf_single_rel_hdr (sec
);
2831 /* Do the actual relocation. */
2833 if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rel
))
2834 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, &count
, data
);
2835 else if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rela
))
2836 mips_elf64_write_rela (abfd
, sec
, rel_hdr
, &count
, data
);
2842 mips_elf64_write_rel (bfd
*abfd
, asection
*sec
,
2843 Elf_Internal_Shdr
*rel_hdr
,
2844 int *count
, void *data
)
2846 bfd_boolean
*failedp
= data
;
2847 Elf64_Mips_External_Rel
*ext_rel
;
2849 asymbol
*last_sym
= 0;
2850 int last_sym_idx
= 0;
2852 rel_hdr
->sh_size
= rel_hdr
->sh_entsize
* *count
;
2853 rel_hdr
->contents
= bfd_alloc (abfd
, rel_hdr
->sh_size
);
2854 if (rel_hdr
->contents
== NULL
)
2860 ext_rel
= (Elf64_Mips_External_Rel
*) rel_hdr
->contents
;
2861 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rel
++)
2864 Elf64_Mips_Internal_Rela int_rel
;
2869 ptr
= sec
->orelocation
[idx
];
2871 /* The address of an ELF reloc is section relative for an object
2872 file, and absolute for an executable file or shared library.
2873 The address of a BFD reloc is always section relative. */
2874 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2875 int_rel
.r_offset
= ptr
->address
;
2877 int_rel
.r_offset
= ptr
->address
+ sec
->vma
;
2879 sym
= *ptr
->sym_ptr_ptr
;
2880 if (sym
== last_sym
)
2882 else if (bfd_is_abs_section (sym
->section
) && sym
->value
== 0)
2887 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2897 int_rel
.r_ssym
= RSS_UNDEF
;
2899 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2900 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2906 int_rel
.r_type
= ptr
->howto
->type
;
2907 int_rel
.r_type2
= (int) R_MIPS_NONE
;
2908 int_rel
.r_type3
= (int) R_MIPS_NONE
;
2910 for (i
= 0; i
< 2; i
++)
2914 if (idx
+ 1 >= sec
->reloc_count
)
2916 r
= sec
->orelocation
[idx
+ 1];
2917 if (r
->address
!= ptr
->address
2918 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2919 || (*r
->sym_ptr_ptr
)->value
!= 0)
2922 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2925 int_rel
.r_type2
= r
->howto
->type
;
2927 int_rel
.r_type3
= r
->howto
->type
;
2932 mips_elf64_swap_reloc_out (abfd
, &int_rel
, ext_rel
);
2935 BFD_ASSERT (ext_rel
- (Elf64_Mips_External_Rel
*) rel_hdr
->contents
2940 mips_elf64_write_rela (bfd
*abfd
, asection
*sec
,
2941 Elf_Internal_Shdr
*rela_hdr
,
2942 int *count
, void *data
)
2944 bfd_boolean
*failedp
= data
;
2945 Elf64_Mips_External_Rela
*ext_rela
;
2947 asymbol
*last_sym
= 0;
2948 int last_sym_idx
= 0;
2950 rela_hdr
->sh_size
= rela_hdr
->sh_entsize
* *count
;
2951 rela_hdr
->contents
= bfd_alloc (abfd
, rela_hdr
->sh_size
);
2952 if (rela_hdr
->contents
== NULL
)
2958 ext_rela
= (Elf64_Mips_External_Rela
*) rela_hdr
->contents
;
2959 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rela
++)
2962 Elf64_Mips_Internal_Rela int_rela
;
2967 ptr
= sec
->orelocation
[idx
];
2969 /* The address of an ELF reloc is section relative for an object
2970 file, and absolute for an executable file or shared library.
2971 The address of a BFD reloc is always section relative. */
2972 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2973 int_rela
.r_offset
= ptr
->address
;
2975 int_rela
.r_offset
= ptr
->address
+ sec
->vma
;
2977 sym
= *ptr
->sym_ptr_ptr
;
2978 if (sym
== last_sym
)
2980 else if (bfd_is_abs_section (sym
->section
) && sym
->value
== 0)
2985 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2995 int_rela
.r_addend
= ptr
->addend
;
2996 int_rela
.r_ssym
= RSS_UNDEF
;
2998 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2999 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
3005 int_rela
.r_type
= ptr
->howto
->type
;
3006 int_rela
.r_type2
= (int) R_MIPS_NONE
;
3007 int_rela
.r_type3
= (int) R_MIPS_NONE
;
3009 for (i
= 0; i
< 2; i
++)
3013 if (idx
+ 1 >= sec
->reloc_count
)
3015 r
= sec
->orelocation
[idx
+ 1];
3016 if (r
->address
!= ptr
->address
3017 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
3018 || (*r
->sym_ptr_ptr
)->value
!= 0)
3021 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3024 int_rela
.r_type2
= r
->howto
->type
;
3026 int_rela
.r_type3
= r
->howto
->type
;
3031 mips_elf64_swap_reloca_out (abfd
, &int_rela
, ext_rela
);
3034 BFD_ASSERT (ext_rela
- (Elf64_Mips_External_Rela
*) rela_hdr
->contents
3038 /* Set the right machine number for a MIPS ELF file. */
3041 mips_elf64_object_p (bfd
*abfd
)
3045 /* Irix 6 is broken. Object file symbol tables are not always
3046 sorted correctly such that local symbols precede global symbols,
3047 and the sh_info field in the symbol table is not always right. */
3048 if (elf64_mips_irix_compat (abfd
) != ict_none
)
3049 elf_bad_symtab (abfd
) = TRUE
;
3051 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
3052 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
3056 /* Depending on the target vector we generate some version of Irix
3057 executables or "normal" MIPS ELF ABI executables. */
3058 static irix_compat_t
3059 elf64_mips_irix_compat (bfd
*abfd
)
3061 if ((abfd
->xvec
== &bfd_elf64_bigmips_vec
)
3062 || (abfd
->xvec
== &bfd_elf64_littlemips_vec
))
3068 /* Support for core dump NOTE sections. */
3070 elf64_mips_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
3075 switch (note
->descsz
)
3080 case 480: /* Linux/MIPS - N64 kernel */
3082 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
3085 elf_tdata (abfd
)->core_lwpid
= bfd_get_32 (abfd
, note
->descdata
+ 32);
3094 /* Make a ".reg/999" section. */
3095 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
3096 size
, note
->descpos
+ offset
);
3100 elf64_mips_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
3102 switch (note
->descsz
)
3107 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
3108 elf_tdata (abfd
)->core_program
3109 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
3110 elf_tdata (abfd
)->core_command
3111 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
3114 /* Note that for some reason, a spurious space is tacked
3115 onto the end of the args in some (at least one anyway)
3116 implementations, so strip it off if it exists. */
3119 char *command
= elf_tdata (abfd
)->core_command
;
3120 int n
= strlen (command
);
3122 if (0 < n
&& command
[n
- 1] == ' ')
3123 command
[n
- 1] = '\0';
3129 /* ECOFF swapping routines. These are used when dealing with the
3130 .mdebug section, which is in the ECOFF debugging format. */
3131 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap
=
3133 /* Symbol table magic number. */
3135 /* Alignment of debugging information. E.g., 4. */
3137 /* Sizes of external symbolic information. */
3138 sizeof (struct hdr_ext
),
3139 sizeof (struct dnr_ext
),
3140 sizeof (struct pdr_ext
),
3141 sizeof (struct sym_ext
),
3142 sizeof (struct opt_ext
),
3143 sizeof (struct fdr_ext
),
3144 sizeof (struct rfd_ext
),
3145 sizeof (struct ext_ext
),
3146 /* Functions to swap in external symbolic data. */
3155 _bfd_ecoff_swap_tir_in
,
3156 _bfd_ecoff_swap_rndx_in
,
3157 /* Functions to swap out external symbolic data. */
3166 _bfd_ecoff_swap_tir_out
,
3167 _bfd_ecoff_swap_rndx_out
,
3168 /* Function to read in symbolic data. */
3169 _bfd_mips_elf_read_ecoff_info
3172 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3173 standard ELF. This structure is used to redirect the relocation
3174 handling routines. */
3176 const struct elf_size_info mips_elf64_size_info
=
3178 sizeof (Elf64_External_Ehdr
),
3179 sizeof (Elf64_External_Phdr
),
3180 sizeof (Elf64_External_Shdr
),
3181 sizeof (Elf64_Mips_External_Rel
),
3182 sizeof (Elf64_Mips_External_Rela
),
3183 sizeof (Elf64_External_Sym
),
3184 sizeof (Elf64_External_Dyn
),
3185 sizeof (Elf_External_Note
),
3186 4, /* hash-table entry size */
3187 3, /* internal relocations per external relocations */
3189 3, /* log_file_align */
3192 bfd_elf64_write_out_phdrs
,
3193 bfd_elf64_write_shdrs_and_ehdr
,
3194 bfd_elf64_checksum_contents
,
3195 mips_elf64_write_relocs
,
3196 bfd_elf64_swap_symbol_in
,
3197 bfd_elf64_swap_symbol_out
,
3198 mips_elf64_slurp_reloc_table
,
3199 bfd_elf64_slurp_symbol_table
,
3200 bfd_elf64_swap_dyn_in
,
3201 bfd_elf64_swap_dyn_out
,
3202 mips_elf64_be_swap_reloc_in
,
3203 mips_elf64_be_swap_reloc_out
,
3204 mips_elf64_be_swap_reloca_in
,
3205 mips_elf64_be_swap_reloca_out
3208 #define ELF_ARCH bfd_arch_mips
3209 #define ELF_TARGET_ID MIPS_ELF_DATA
3210 #define ELF_MACHINE_CODE EM_MIPS
3212 #define elf_backend_collect TRUE
3213 #define elf_backend_type_change_ok TRUE
3214 #define elf_backend_can_gc_sections TRUE
3215 #define elf_info_to_howto mips_elf64_info_to_howto_rela
3216 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
3217 #define elf_backend_object_p mips_elf64_object_p
3218 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3219 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3220 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3221 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3222 #define elf_backend_section_from_bfd_section \
3223 _bfd_mips_elf_section_from_bfd_section
3224 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3225 #define elf_backend_link_output_symbol_hook \
3226 _bfd_mips_elf_link_output_symbol_hook
3227 #define elf_backend_create_dynamic_sections \
3228 _bfd_mips_elf_create_dynamic_sections
3229 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3230 #define elf_backend_merge_symbol_attribute \
3231 _bfd_mips_elf_merge_symbol_attribute
3232 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
3233 #define elf_backend_adjust_dynamic_symbol \
3234 _bfd_mips_elf_adjust_dynamic_symbol
3235 #define elf_backend_always_size_sections \
3236 _bfd_mips_elf_always_size_sections
3237 #define elf_backend_size_dynamic_sections \
3238 _bfd_mips_elf_size_dynamic_sections
3239 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
3240 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3241 #define elf_backend_finish_dynamic_symbol \
3242 _bfd_mips_elf_finish_dynamic_symbol
3243 #define elf_backend_finish_dynamic_sections \
3244 _bfd_mips_elf_finish_dynamic_sections
3245 #define elf_backend_final_write_processing \
3246 _bfd_mips_elf_final_write_processing
3247 #define elf_backend_additional_program_headers \
3248 _bfd_mips_elf_additional_program_headers
3249 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3250 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3251 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3252 #define elf_backend_copy_indirect_symbol \
3253 _bfd_mips_elf_copy_indirect_symbol
3254 #define elf_backend_ignore_discarded_relocs \
3255 _bfd_mips_elf_ignore_discarded_relocs
3256 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
3257 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3258 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3259 #define elf_backend_size_info mips_elf64_size_info
3261 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3262 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
3264 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3266 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3267 work better/work only in RELA, so we default to this. */
3268 #define elf_backend_may_use_rel_p 1
3269 #define elf_backend_may_use_rela_p 1
3270 #define elf_backend_default_use_rela_p 1
3271 #define elf_backend_rela_plts_and_copies_p 0
3272 #define elf_backend_plt_readonly 1
3273 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
3275 #define elf_backend_sign_extend_vma TRUE
3277 #define elf_backend_write_section _bfd_mips_elf_write_section
3279 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3280 MIPS-specific function only applies to IRIX5, which had no 64-bit
3282 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
3283 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
3284 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
3285 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
3286 #define bfd_elf64_bfd_get_relocated_section_contents \
3287 _bfd_elf_mips_get_relocated_section_contents
3288 #define bfd_elf64_bfd_link_hash_table_create \
3289 _bfd_mips_elf_link_hash_table_create
3290 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
3291 #define bfd_elf64_bfd_merge_private_bfd_data \
3292 _bfd_mips_elf_merge_private_bfd_data
3293 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3294 #define bfd_elf64_bfd_print_private_bfd_data \
3295 _bfd_mips_elf_print_private_bfd_data
3297 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3298 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3299 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3300 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3301 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
3303 /* MIPS ELF64 archive functions. */
3304 #define bfd_elf64_archive_functions
3305 extern bfd_boolean bfd_elf64_archive_slurp_armap
3307 extern bfd_boolean bfd_elf64_archive_write_armap
3308 (bfd
*, unsigned int, struct orl
*, unsigned int, int);
3309 #define bfd_elf64_archive_slurp_extended_name_table \
3310 _bfd_archive_coff_slurp_extended_name_table
3311 #define bfd_elf64_archive_construct_extended_name_table \
3312 _bfd_archive_coff_construct_extended_name_table
3313 #define bfd_elf64_archive_truncate_arname \
3314 _bfd_archive_coff_truncate_arname
3315 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3316 #define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_ar_hdr
3317 #define bfd_elf64_archive_openr_next_archived_file \
3318 _bfd_archive_coff_openr_next_archived_file
3319 #define bfd_elf64_archive_get_elt_at_index \
3320 _bfd_archive_coff_get_elt_at_index
3321 #define bfd_elf64_archive_generic_stat_arch_elt \
3322 _bfd_archive_coff_generic_stat_arch_elt
3323 #define bfd_elf64_archive_update_armap_timestamp \
3324 _bfd_archive_coff_update_armap_timestamp
3326 /* The SGI style (n)64 NewABI. */
3327 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3328 #define TARGET_LITTLE_NAME "elf64-littlemips"
3329 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3330 #define TARGET_BIG_NAME "elf64-bigmips"
3332 #define ELF_MAXPAGESIZE 0x10000
3333 #define ELF_COMMONPAGESIZE 0x1000
3335 #include "elf64-target.h"
3337 /* The SYSV-style 'traditional' (n)64 NewABI. */
3338 #undef TARGET_LITTLE_SYM
3339 #undef TARGET_LITTLE_NAME
3340 #undef TARGET_BIG_SYM
3341 #undef TARGET_BIG_NAME
3343 #undef ELF_MAXPAGESIZE
3344 #undef ELF_COMMONPAGESIZE
3346 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3347 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3348 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3349 #define TARGET_BIG_NAME "elf64-tradbigmips"
3351 #define ELF_MAXPAGESIZE 0x10000
3352 #define ELF_COMMONPAGESIZE 0x1000
3353 #define elf64_bed elf64_tradbed
3355 /* Include the target file again for this target. */
3356 #include "elf64-target.h"
3359 /* FreeBSD support. */
3361 #undef TARGET_LITTLE_SYM
3362 #undef TARGET_LITTLE_NAME
3363 #undef TARGET_BIG_SYM
3364 #undef TARGET_BIG_NAME
3366 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_freebsd_vec
3367 #define TARGET_LITTLE_NAME "elf64-tradlittlemips-freebsd"
3368 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_freebsd_vec
3369 #define TARGET_BIG_NAME "elf64-tradbigmips-freebsd"
3372 #define ELF_OSABI ELFOSABI_FREEBSD
3374 /* The kernel recognizes executables as valid only if they carry a
3375 "FreeBSD" label in the ELF header. So we put this label on all
3376 executables and (for simplicity) also all other object files. */
3379 elf_fbsd_post_process_headers (bfd
*abfd
, struct bfd_link_info
*info
)
3381 _bfd_elf_set_osabi (abfd
, info
);
3384 #undef elf_backend_post_process_headers
3385 #define elf_backend_post_process_headers elf_fbsd_post_process_headers
3387 #define elf64_bed elf64_fbsd_tradbed
3389 #include "elf64-target.h"