1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4 Ian Lance Taylor, Cygnus Support
5 Linker support added by Mark Mitchell, CodeSourcery, LLC.
6 <mark@codesourcery.com>
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 /* This file supports the 64-bit MIPS ELF ABI.
26 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
27 overrides the usual ELF reloc handling, and handles reading and
28 writing the relocations here. */
30 /* TODO: Many things are unsupported, even if there is some code for it
31 . (which was mostly stolen from elf32-mips.c and slightly adapted).
33 . - Relocation handling for REL relocs is wrong in many cases and
35 . - Relocation handling for RELA relocs related to GOT support are
36 . also likely to be wrong.
37 . - Support for MIPS16 is untested.
38 . - Combined relocs with RSS_* entries are unsupported.
39 . - The whole GOT handling for NewABI is missing, some parts of
40 . the OldABI version is still lying around and should be removed.
50 #include "elfxx-mips.h"
53 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
54 use ECOFF. However, we support it anyhow for an easier changeover. */
56 #include "coff/symconst.h"
57 #include "coff/internal.h"
58 #include "coff/ecoff.h"
59 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
60 #include "coff/alpha.h"
61 #define ECOFF_SIGNED_64
62 #include "ecoffswap.h"
64 static void mips_elf64_swap_reloc_in
65 (bfd
*, const Elf64_Mips_External_Rel
*, Elf64_Mips_Internal_Rela
*);
66 static void mips_elf64_swap_reloca_in
67 (bfd
*, const Elf64_Mips_External_Rela
*, Elf64_Mips_Internal_Rela
*);
68 static void mips_elf64_swap_reloc_out
69 (bfd
*, const Elf64_Mips_Internal_Rela
*, Elf64_Mips_External_Rel
*);
70 static void mips_elf64_swap_reloca_out
71 (bfd
*, const Elf64_Mips_Internal_Rela
*, Elf64_Mips_External_Rela
*);
72 static void mips_elf64_be_swap_reloc_in
73 (bfd
*, const bfd_byte
*, Elf_Internal_Rela
*);
74 static void mips_elf64_be_swap_reloc_out
75 (bfd
*, const Elf_Internal_Rela
*, bfd_byte
*);
76 static void mips_elf64_be_swap_reloca_in
77 (bfd
*, const bfd_byte
*, Elf_Internal_Rela
*);
78 static void mips_elf64_be_swap_reloca_out
79 (bfd
*, const Elf_Internal_Rela
*, bfd_byte
*);
80 static reloc_howto_type
*bfd_elf64_bfd_reloc_type_lookup
81 (bfd
*, bfd_reloc_code_real_type
);
82 static reloc_howto_type
*mips_elf64_rtype_to_howto
83 (unsigned int, bfd_boolean
);
84 static void mips_elf64_info_to_howto_rel
85 (bfd
*, arelent
*, Elf_Internal_Rela
*);
86 static void mips_elf64_info_to_howto_rela
87 (bfd
*, arelent
*, Elf_Internal_Rela
*);
88 static long mips_elf64_get_reloc_upper_bound
90 static long mips_elf64_canonicalize_reloc
91 (bfd
*, asection
*, arelent
**, asymbol
**);
92 static long mips_elf64_get_dynamic_reloc_upper_bound
94 static long mips_elf64_canonicalize_dynamic_reloc
95 (bfd
*, arelent
**, asymbol
**);
96 static bfd_boolean mips_elf64_slurp_one_reloc_table
97 (bfd
*, asection
*, Elf_Internal_Shdr
*, bfd_size_type
, arelent
*,
98 asymbol
**, bfd_boolean
);
99 static bfd_boolean mips_elf64_slurp_reloc_table
100 (bfd
*, asection
*, asymbol
**, bfd_boolean
);
101 static void mips_elf64_write_relocs
102 (bfd
*, asection
*, void *);
103 static void mips_elf64_write_rel
104 (bfd
*, asection
*, Elf_Internal_Shdr
*, int *, void *);
105 static void mips_elf64_write_rela
106 (bfd
*, asection
*, Elf_Internal_Shdr
*, int *, void *);
107 static bfd_reloc_status_type mips_elf64_gprel16_reloc
108 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
109 static bfd_reloc_status_type mips_elf64_literal_reloc
110 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
111 static bfd_reloc_status_type mips_elf64_gprel32_reloc
112 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
113 static bfd_reloc_status_type mips_elf64_shift6_reloc
114 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
115 static bfd_reloc_status_type mips16_jump_reloc
116 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
117 static bfd_reloc_status_type mips16_gprel_reloc
118 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
119 static bfd_boolean mips_elf64_assign_gp
121 static bfd_reloc_status_type mips_elf64_final_gp
122 (bfd
*, asymbol
*, bfd_boolean
, char **, bfd_vma
*);
123 static bfd_boolean mips_elf64_object_p
125 static irix_compat_t elf64_mips_irix_compat
127 static bfd_boolean elf64_mips_grok_prstatus
128 (bfd
*, Elf_Internal_Note
*);
129 static bfd_boolean elf64_mips_grok_psinfo
130 (bfd
*, Elf_Internal_Note
*);
132 extern const bfd_target bfd_elf64_bigmips_vec
;
133 extern const bfd_target bfd_elf64_littlemips_vec
;
135 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
136 from smaller values. Start with zero, widen, *then* decrement. */
137 #define MINUS_ONE (((bfd_vma)0) - 1)
139 /* The number of local .got entries we reserve. */
140 #define MIPS_RESERVED_GOTNO (2)
142 /* The relocation table used for SHT_REL sections. */
144 static reloc_howto_type mips_elf64_howto_table_rel
[] =
147 HOWTO (R_MIPS_NONE
, /* type */
149 0, /* size (0 = byte, 1 = short, 2 = long) */
151 FALSE
, /* pc_relative */
153 complain_overflow_dont
, /* complain_on_overflow */
154 _bfd_mips_elf_generic_reloc
, /* special_function */
155 "R_MIPS_NONE", /* name */
156 FALSE
, /* partial_inplace */
159 FALSE
), /* pcrel_offset */
161 /* 16 bit relocation. */
162 HOWTO (R_MIPS_16
, /* type */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
166 FALSE
, /* pc_relative */
168 complain_overflow_signed
, /* complain_on_overflow */
169 _bfd_mips_elf_generic_reloc
, /* special_function */
170 "R_MIPS_16", /* name */
171 TRUE
, /* partial_inplace */
172 0x0000ffff, /* src_mask */
173 0x0000ffff, /* dst_mask */
174 FALSE
), /* pcrel_offset */
176 /* 32 bit relocation. */
177 HOWTO (R_MIPS_32
, /* type */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
181 FALSE
, /* pc_relative */
183 complain_overflow_dont
, /* complain_on_overflow */
184 _bfd_mips_elf_generic_reloc
, /* special_function */
185 "R_MIPS_32", /* name */
186 TRUE
, /* partial_inplace */
187 0xffffffff, /* src_mask */
188 0xffffffff, /* dst_mask */
189 FALSE
), /* pcrel_offset */
191 /* 32 bit symbol relative relocation. */
192 HOWTO (R_MIPS_REL32
, /* type */
194 2, /* size (0 = byte, 1 = short, 2 = long) */
196 FALSE
, /* pc_relative */
198 complain_overflow_dont
, /* complain_on_overflow */
199 _bfd_mips_elf_generic_reloc
, /* special_function */
200 "R_MIPS_REL32", /* name */
201 TRUE
, /* partial_inplace */
202 0xffffffff, /* src_mask */
203 0xffffffff, /* dst_mask */
204 FALSE
), /* pcrel_offset */
206 /* 26 bit jump address. */
207 HOWTO (R_MIPS_26
, /* type */
209 2, /* size (0 = byte, 1 = short, 2 = long) */
211 FALSE
, /* pc_relative */
213 complain_overflow_dont
, /* complain_on_overflow */
214 /* This needs complex overflow
215 detection, because the upper 36
216 bits must match the PC + 4. */
217 _bfd_mips_elf_generic_reloc
, /* special_function */
218 "R_MIPS_26", /* name */
219 TRUE
, /* partial_inplace */
220 0x03ffffff, /* src_mask */
221 0x03ffffff, /* dst_mask */
222 FALSE
), /* pcrel_offset */
224 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
225 However, the native IRIX6 tools use them, so we try our best. */
227 /* High 16 bits of symbol value. */
228 HOWTO (R_MIPS_HI16
, /* type */
230 2, /* size (0 = byte, 1 = short, 2 = long) */
232 FALSE
, /* pc_relative */
234 complain_overflow_dont
, /* complain_on_overflow */
235 _bfd_mips_elf_hi16_reloc
, /* special_function */
236 "R_MIPS_HI16", /* name */
237 TRUE
, /* partial_inplace */
238 0x0000ffff, /* src_mask */
239 0x0000ffff, /* dst_mask */
240 FALSE
), /* pcrel_offset */
242 /* Low 16 bits of symbol value. */
243 HOWTO (R_MIPS_LO16
, /* type */
245 2, /* size (0 = byte, 1 = short, 2 = long) */
247 FALSE
, /* pc_relative */
249 complain_overflow_dont
, /* complain_on_overflow */
250 _bfd_mips_elf_lo16_reloc
, /* special_function */
251 "R_MIPS_LO16", /* name */
252 TRUE
, /* partial_inplace */
253 0x0000ffff, /* src_mask */
254 0x0000ffff, /* dst_mask */
255 FALSE
), /* pcrel_offset */
257 /* GP relative reference. */
258 HOWTO (R_MIPS_GPREL16
, /* type */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
262 FALSE
, /* pc_relative */
264 complain_overflow_signed
, /* complain_on_overflow */
265 mips_elf64_gprel16_reloc
, /* special_function */
266 "R_MIPS_GPREL16", /* name */
267 TRUE
, /* partial_inplace */
268 0x0000ffff, /* src_mask */
269 0x0000ffff, /* dst_mask */
270 FALSE
), /* pcrel_offset */
272 /* Reference to literal section. */
273 HOWTO (R_MIPS_LITERAL
, /* type */
275 2, /* size (0 = byte, 1 = short, 2 = long) */
277 FALSE
, /* pc_relative */
279 complain_overflow_signed
, /* complain_on_overflow */
280 mips_elf64_literal_reloc
, /* special_function */
281 "R_MIPS_LITERAL", /* name */
282 TRUE
, /* partial_inplace */
283 0x0000ffff, /* src_mask */
284 0x0000ffff, /* dst_mask */
285 FALSE
), /* pcrel_offset */
287 /* Reference to global offset table. */
288 HOWTO (R_MIPS_GOT16
, /* type */
290 2, /* size (0 = byte, 1 = short, 2 = long) */
292 FALSE
, /* pc_relative */
294 complain_overflow_signed
, /* complain_on_overflow */
295 _bfd_mips_elf_got16_reloc
, /* special_function */
296 "R_MIPS_GOT16", /* name */
297 TRUE
, /* partial_inplace */
298 0x0000ffff, /* src_mask */
299 0x0000ffff, /* dst_mask */
300 FALSE
), /* pcrel_offset */
302 /* 16 bit PC relative reference. */
303 HOWTO (R_MIPS_PC16
, /* type */
305 2, /* size (0 = byte, 1 = short, 2 = long) */
307 TRUE
, /* pc_relative */
309 complain_overflow_signed
, /* complain_on_overflow */
310 _bfd_mips_elf_generic_reloc
, /* special_function */
311 "R_MIPS_PC16", /* name */
312 TRUE
, /* partial_inplace */
313 0x0000ffff, /* src_mask */
314 0x0000ffff, /* dst_mask */
315 TRUE
), /* pcrel_offset */
317 /* 16 bit call through global offset table. */
318 HOWTO (R_MIPS_CALL16
, /* type */
320 2, /* size (0 = byte, 1 = short, 2 = long) */
322 FALSE
, /* pc_relative */
324 complain_overflow_signed
, /* complain_on_overflow */
325 _bfd_mips_elf_generic_reloc
, /* special_function */
326 "R_MIPS_CALL16", /* name */
327 TRUE
, /* partial_inplace */
328 0x0000ffff, /* src_mask */
329 0x0000ffff, /* dst_mask */
330 FALSE
), /* pcrel_offset */
332 /* 32 bit GP relative reference. */
333 HOWTO (R_MIPS_GPREL32
, /* type */
335 2, /* size (0 = byte, 1 = short, 2 = long) */
337 FALSE
, /* pc_relative */
339 complain_overflow_dont
, /* complain_on_overflow */
340 mips_elf64_gprel32_reloc
, /* special_function */
341 "R_MIPS_GPREL32", /* name */
342 TRUE
, /* partial_inplace */
343 0xffffffff, /* src_mask */
344 0xffffffff, /* dst_mask */
345 FALSE
), /* pcrel_offset */
351 /* A 5 bit shift field. */
352 HOWTO (R_MIPS_SHIFT5
, /* type */
354 2, /* size (0 = byte, 1 = short, 2 = long) */
356 FALSE
, /* pc_relative */
358 complain_overflow_bitfield
, /* complain_on_overflow */
359 _bfd_mips_elf_generic_reloc
, /* special_function */
360 "R_MIPS_SHIFT5", /* name */
361 TRUE
, /* partial_inplace */
362 0x000007c0, /* src_mask */
363 0x000007c0, /* dst_mask */
364 FALSE
), /* pcrel_offset */
366 /* A 6 bit shift field. */
367 HOWTO (R_MIPS_SHIFT6
, /* type */
369 2, /* size (0 = byte, 1 = short, 2 = long) */
371 FALSE
, /* pc_relative */
373 complain_overflow_bitfield
, /* complain_on_overflow */
374 mips_elf64_shift6_reloc
, /* special_function */
375 "R_MIPS_SHIFT6", /* name */
376 TRUE
, /* partial_inplace */
377 0x000007c4, /* src_mask */
378 0x000007c4, /* dst_mask */
379 FALSE
), /* pcrel_offset */
381 /* 64 bit relocation. */
382 HOWTO (R_MIPS_64
, /* type */
384 4, /* size (0 = byte, 1 = short, 2 = long) */
386 FALSE
, /* pc_relative */
388 complain_overflow_dont
, /* complain_on_overflow */
389 _bfd_mips_elf_generic_reloc
, /* special_function */
390 "R_MIPS_64", /* name */
391 TRUE
, /* partial_inplace */
392 MINUS_ONE
, /* src_mask */
393 MINUS_ONE
, /* dst_mask */
394 FALSE
), /* pcrel_offset */
396 /* Displacement in the global offset table. */
397 HOWTO (R_MIPS_GOT_DISP
, /* type */
399 2, /* size (0 = byte, 1 = short, 2 = long) */
401 FALSE
, /* pc_relative */
403 complain_overflow_signed
, /* complain_on_overflow */
404 _bfd_mips_elf_generic_reloc
, /* special_function */
405 "R_MIPS_GOT_DISP", /* name */
406 TRUE
, /* partial_inplace */
407 0x0000ffff, /* src_mask */
408 0x0000ffff, /* dst_mask */
409 FALSE
), /* pcrel_offset */
411 /* Displacement to page pointer in the global offset table. */
412 HOWTO (R_MIPS_GOT_PAGE
, /* type */
414 2, /* size (0 = byte, 1 = short, 2 = long) */
416 FALSE
, /* pc_relative */
418 complain_overflow_signed
, /* complain_on_overflow */
419 _bfd_mips_elf_generic_reloc
, /* special_function */
420 "R_MIPS_GOT_PAGE", /* name */
421 TRUE
, /* partial_inplace */
422 0x0000ffff, /* src_mask */
423 0x0000ffff, /* dst_mask */
424 FALSE
), /* pcrel_offset */
426 /* Offset from page pointer in the global offset table. */
427 HOWTO (R_MIPS_GOT_OFST
, /* type */
429 2, /* size (0 = byte, 1 = short, 2 = long) */
431 FALSE
, /* pc_relative */
433 complain_overflow_signed
, /* complain_on_overflow */
434 _bfd_mips_elf_generic_reloc
, /* special_function */
435 "R_MIPS_GOT_OFST", /* name */
436 TRUE
, /* partial_inplace */
437 0x0000ffff, /* src_mask */
438 0x0000ffff, /* dst_mask */
439 FALSE
), /* pcrel_offset */
441 /* High 16 bits of displacement in global offset table. */
442 HOWTO (R_MIPS_GOT_HI16
, /* type */
444 2, /* size (0 = byte, 1 = short, 2 = long) */
446 FALSE
, /* pc_relative */
448 complain_overflow_dont
, /* complain_on_overflow */
449 _bfd_mips_elf_generic_reloc
, /* special_function */
450 "R_MIPS_GOT_HI16", /* name */
451 TRUE
, /* partial_inplace */
452 0x0000ffff, /* src_mask */
453 0x0000ffff, /* dst_mask */
454 FALSE
), /* pcrel_offset */
456 /* Low 16 bits of displacement in global offset table. */
457 HOWTO (R_MIPS_GOT_LO16
, /* type */
459 2, /* size (0 = byte, 1 = short, 2 = long) */
461 FALSE
, /* pc_relative */
463 complain_overflow_dont
, /* complain_on_overflow */
464 _bfd_mips_elf_generic_reloc
, /* special_function */
465 "R_MIPS_GOT_LO16", /* name */
466 TRUE
, /* partial_inplace */
467 0x0000ffff, /* src_mask */
468 0x0000ffff, /* dst_mask */
469 FALSE
), /* pcrel_offset */
471 /* 64 bit subtraction. */
472 HOWTO (R_MIPS_SUB
, /* type */
474 4, /* size (0 = byte, 1 = short, 2 = long) */
476 FALSE
, /* pc_relative */
478 complain_overflow_dont
, /* complain_on_overflow */
479 _bfd_mips_elf_generic_reloc
, /* special_function */
480 "R_MIPS_SUB", /* name */
481 TRUE
, /* partial_inplace */
482 MINUS_ONE
, /* src_mask */
483 MINUS_ONE
, /* dst_mask */
484 FALSE
), /* pcrel_offset */
486 /* Insert the addend as an instruction. */
487 /* FIXME: Not handled correctly. */
488 HOWTO (R_MIPS_INSERT_A
, /* type */
490 2, /* size (0 = byte, 1 = short, 2 = long) */
492 FALSE
, /* pc_relative */
494 complain_overflow_dont
, /* complain_on_overflow */
495 _bfd_mips_elf_generic_reloc
, /* special_function */
496 "R_MIPS_INSERT_A", /* name */
497 TRUE
, /* partial_inplace */
498 0xffffffff, /* src_mask */
499 0xffffffff, /* dst_mask */
500 FALSE
), /* pcrel_offset */
502 /* Insert the addend as an instruction, and change all relocations
503 to refer to the old instruction at the address. */
504 /* FIXME: Not handled correctly. */
505 HOWTO (R_MIPS_INSERT_B
, /* type */
507 2, /* size (0 = byte, 1 = short, 2 = long) */
509 FALSE
, /* pc_relative */
511 complain_overflow_dont
, /* complain_on_overflow */
512 _bfd_mips_elf_generic_reloc
, /* special_function */
513 "R_MIPS_INSERT_B", /* name */
514 TRUE
, /* partial_inplace */
515 0xffffffff, /* src_mask */
516 0xffffffff, /* dst_mask */
517 FALSE
), /* pcrel_offset */
519 /* Delete a 32 bit instruction. */
520 /* FIXME: Not handled correctly. */
521 HOWTO (R_MIPS_DELETE
, /* type */
523 2, /* size (0 = byte, 1 = short, 2 = long) */
525 FALSE
, /* pc_relative */
527 complain_overflow_dont
, /* complain_on_overflow */
528 _bfd_mips_elf_generic_reloc
, /* special_function */
529 "R_MIPS_DELETE", /* name */
530 TRUE
, /* partial_inplace */
531 0xffffffff, /* src_mask */
532 0xffffffff, /* dst_mask */
533 FALSE
), /* pcrel_offset */
535 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
537 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
538 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
540 b) No other NewABI toolchain actually emits such relocations. */
541 EMPTY_HOWTO (R_MIPS_HIGHER
),
542 EMPTY_HOWTO (R_MIPS_HIGHEST
),
544 /* High 16 bits of displacement in global offset table. */
545 HOWTO (R_MIPS_CALL_HI16
, /* type */
547 2, /* size (0 = byte, 1 = short, 2 = long) */
549 FALSE
, /* pc_relative */
551 complain_overflow_dont
, /* complain_on_overflow */
552 _bfd_mips_elf_generic_reloc
, /* special_function */
553 "R_MIPS_CALL_HI16", /* name */
554 TRUE
, /* partial_inplace */
555 0x0000ffff, /* src_mask */
556 0x0000ffff, /* dst_mask */
557 FALSE
), /* pcrel_offset */
559 /* Low 16 bits of displacement in global offset table. */
560 HOWTO (R_MIPS_CALL_LO16
, /* type */
562 2, /* size (0 = byte, 1 = short, 2 = long) */
564 FALSE
, /* pc_relative */
566 complain_overflow_dont
, /* complain_on_overflow */
567 _bfd_mips_elf_generic_reloc
, /* special_function */
568 "R_MIPS_CALL_LO16", /* name */
569 TRUE
, /* partial_inplace */
570 0x0000ffff, /* src_mask */
571 0x0000ffff, /* dst_mask */
572 FALSE
), /* pcrel_offset */
574 /* Section displacement, used by an associated event location section. */
575 HOWTO (R_MIPS_SCN_DISP
, /* type */
577 2, /* size (0 = byte, 1 = short, 2 = long) */
579 FALSE
, /* pc_relative */
581 complain_overflow_dont
, /* complain_on_overflow */
582 _bfd_mips_elf_generic_reloc
, /* special_function */
583 "R_MIPS_SCN_DISP", /* name */
584 TRUE
, /* partial_inplace */
585 0xffffffff, /* src_mask */
586 0xffffffff, /* dst_mask */
587 FALSE
), /* pcrel_offset */
589 HOWTO (R_MIPS_REL16
, /* type */
591 1, /* size (0 = byte, 1 = short, 2 = long) */
593 FALSE
, /* pc_relative */
595 complain_overflow_signed
, /* complain_on_overflow */
596 _bfd_mips_elf_generic_reloc
, /* special_function */
597 "R_MIPS_REL16", /* name */
598 TRUE
, /* partial_inplace */
599 0xffff, /* src_mask */
600 0xffff, /* dst_mask */
601 FALSE
), /* pcrel_offset */
603 /* These two are obsolete. */
604 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
605 EMPTY_HOWTO (R_MIPS_PJUMP
),
607 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
608 It must be used for multigot GOT's (and only there). */
609 HOWTO (R_MIPS_RELGOT
, /* type */
611 2, /* size (0 = byte, 1 = short, 2 = long) */
613 FALSE
, /* pc_relative */
615 complain_overflow_dont
, /* complain_on_overflow */
616 _bfd_mips_elf_generic_reloc
, /* special_function */
617 "R_MIPS_RELGOT", /* name */
618 TRUE
, /* partial_inplace */
619 0xffffffff, /* src_mask */
620 0xffffffff, /* dst_mask */
621 FALSE
), /* pcrel_offset */
623 /* Protected jump conversion. This is an optimization hint. No
624 relocation is required for correctness. */
625 HOWTO (R_MIPS_JALR
, /* type */
627 2, /* size (0 = byte, 1 = short, 2 = long) */
629 FALSE
, /* pc_relative */
631 complain_overflow_dont
, /* complain_on_overflow */
632 _bfd_mips_elf_generic_reloc
, /* special_function */
633 "R_MIPS_JALR", /* name */
634 FALSE
, /* partial_inplace */
636 0x00000000, /* dst_mask */
637 FALSE
), /* pcrel_offset */
639 /* TLS relocations. */
640 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32
),
641 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32
),
643 HOWTO (R_MIPS_TLS_DTPMOD64
, /* type */
645 4, /* size (0 = byte, 1 = short, 2 = long) */
647 FALSE
, /* pc_relative */
649 complain_overflow_dont
, /* complain_on_overflow */
650 _bfd_mips_elf_generic_reloc
, /* special_function */
651 "R_MIPS_TLS_DTPMOD64", /* name */
652 TRUE
, /* partial_inplace */
653 MINUS_ONE
, /* src_mask */
654 MINUS_ONE
, /* dst_mask */
655 FALSE
), /* pcrel_offset */
657 HOWTO (R_MIPS_TLS_DTPREL64
, /* type */
659 4, /* size (0 = byte, 1 = short, 2 = long) */
661 FALSE
, /* pc_relative */
663 complain_overflow_dont
, /* complain_on_overflow */
664 _bfd_mips_elf_generic_reloc
, /* special_function */
665 "R_MIPS_TLS_DTPREL64", /* name */
666 TRUE
, /* partial_inplace */
667 MINUS_ONE
, /* src_mask */
668 MINUS_ONE
, /* dst_mask */
669 FALSE
), /* pcrel_offset */
671 /* TLS general dynamic variable reference. */
672 HOWTO (R_MIPS_TLS_GD
, /* type */
674 2, /* size (0 = byte, 1 = short, 2 = long) */
676 FALSE
, /* pc_relative */
678 complain_overflow_signed
, /* complain_on_overflow */
679 _bfd_mips_elf_generic_reloc
, /* special_function */
680 "R_MIPS_TLS_GD", /* name */
681 TRUE
, /* partial_inplace */
682 0x0000ffff, /* src_mask */
683 0x0000ffff, /* dst_mask */
684 FALSE
), /* pcrel_offset */
686 /* TLS local dynamic variable reference. */
687 HOWTO (R_MIPS_TLS_LDM
, /* type */
689 2, /* size (0 = byte, 1 = short, 2 = long) */
691 FALSE
, /* pc_relative */
693 complain_overflow_signed
, /* complain_on_overflow */
694 _bfd_mips_elf_generic_reloc
, /* special_function */
695 "R_MIPS_TLS_LDM", /* name */
696 TRUE
, /* partial_inplace */
697 0x0000ffff, /* src_mask */
698 0x0000ffff, /* dst_mask */
699 FALSE
), /* pcrel_offset */
701 /* TLS local dynamic offset. */
702 HOWTO (R_MIPS_TLS_DTPREL_HI16
, /* type */
704 2, /* size (0 = byte, 1 = short, 2 = long) */
706 FALSE
, /* pc_relative */
708 complain_overflow_signed
, /* complain_on_overflow */
709 _bfd_mips_elf_generic_reloc
, /* special_function */
710 "R_MIPS_TLS_DTPREL_HI16", /* name */
711 TRUE
, /* partial_inplace */
712 0x0000ffff, /* src_mask */
713 0x0000ffff, /* dst_mask */
714 FALSE
), /* pcrel_offset */
716 /* TLS local dynamic offset. */
717 HOWTO (R_MIPS_TLS_DTPREL_LO16
, /* type */
719 2, /* size (0 = byte, 1 = short, 2 = long) */
721 FALSE
, /* pc_relative */
723 complain_overflow_signed
, /* complain_on_overflow */
724 _bfd_mips_elf_generic_reloc
, /* special_function */
725 "R_MIPS_TLS_DTPREL_LO16", /* name */
726 TRUE
, /* partial_inplace */
727 0x0000ffff, /* src_mask */
728 0x0000ffff, /* dst_mask */
729 FALSE
), /* pcrel_offset */
731 /* TLS thread pointer offset. */
732 HOWTO (R_MIPS_TLS_GOTTPREL
, /* type */
734 2, /* size (0 = byte, 1 = short, 2 = long) */
736 FALSE
, /* pc_relative */
738 complain_overflow_signed
, /* complain_on_overflow */
739 _bfd_mips_elf_generic_reloc
, /* special_function */
740 "R_MIPS_TLS_GOTTPREL", /* name */
741 TRUE
, /* partial_inplace */
742 0x0000ffff, /* src_mask */
743 0x0000ffff, /* dst_mask */
744 FALSE
), /* pcrel_offset */
746 /* TLS IE dynamic relocations. */
747 EMPTY_HOWTO (R_MIPS_TLS_TPREL32
),
749 HOWTO (R_MIPS_TLS_TPREL64
, /* type */
751 4, /* size (0 = byte, 1 = short, 2 = long) */
753 FALSE
, /* pc_relative */
755 complain_overflow_dont
, /* complain_on_overflow */
756 _bfd_mips_elf_generic_reloc
, /* special_function */
757 "R_MIPS_TLS_TPREL64", /* name */
758 TRUE
, /* partial_inplace */
759 MINUS_ONE
, /* src_mask */
760 MINUS_ONE
, /* dst_mask */
761 FALSE
), /* pcrel_offset */
763 /* TLS thread pointer offset. */
764 HOWTO (R_MIPS_TLS_TPREL_HI16
, /* type */
766 2, /* size (0 = byte, 1 = short, 2 = long) */
768 FALSE
, /* pc_relative */
770 complain_overflow_signed
, /* complain_on_overflow */
771 _bfd_mips_elf_generic_reloc
, /* special_function */
772 "R_MIPS_TLS_TPREL_HI16", /* name */
773 TRUE
, /* partial_inplace */
774 0x0000ffff, /* src_mask */
775 0x0000ffff, /* dst_mask */
776 FALSE
), /* pcrel_offset */
778 /* TLS thread pointer offset. */
779 HOWTO (R_MIPS_TLS_TPREL_LO16
, /* type */
781 2, /* size (0 = byte, 1 = short, 2 = long) */
783 FALSE
, /* pc_relative */
785 complain_overflow_signed
, /* complain_on_overflow */
786 _bfd_mips_elf_generic_reloc
, /* special_function */
787 "R_MIPS_TLS_TPREL_LO16", /* name */
788 TRUE
, /* partial_inplace */
789 0x0000ffff, /* src_mask */
790 0x0000ffff, /* dst_mask */
791 FALSE
), /* pcrel_offset */
794 /* The relocation table used for SHT_RELA sections. */
796 static reloc_howto_type mips_elf64_howto_table_rela
[] =
799 HOWTO (R_MIPS_NONE
, /* type */
801 0, /* size (0 = byte, 1 = short, 2 = long) */
803 FALSE
, /* pc_relative */
805 complain_overflow_dont
, /* complain_on_overflow */
806 _bfd_mips_elf_generic_reloc
, /* special_function */
807 "R_MIPS_NONE", /* name */
808 FALSE
, /* partial_inplace */
811 FALSE
), /* pcrel_offset */
813 /* 16 bit relocation. */
814 HOWTO (R_MIPS_16
, /* type */
816 2, /* size (0 = byte, 1 = short, 2 = long) */
818 FALSE
, /* pc_relative */
820 complain_overflow_signed
, /* complain_on_overflow */
821 _bfd_mips_elf_generic_reloc
, /* special_function */
822 "R_MIPS_16", /* name */
823 FALSE
, /* partial_inplace */
825 0x0000ffff, /* dst_mask */
826 FALSE
), /* pcrel_offset */
828 /* 32 bit relocation. */
829 HOWTO (R_MIPS_32
, /* type */
831 2, /* size (0 = byte, 1 = short, 2 = long) */
833 FALSE
, /* pc_relative */
835 complain_overflow_dont
, /* complain_on_overflow */
836 _bfd_mips_elf_generic_reloc
, /* special_function */
837 "R_MIPS_32", /* name */
838 FALSE
, /* partial_inplace */
840 0xffffffff, /* dst_mask */
841 FALSE
), /* pcrel_offset */
843 /* 32 bit symbol relative relocation. */
844 HOWTO (R_MIPS_REL32
, /* type */
846 2, /* size (0 = byte, 1 = short, 2 = long) */
848 FALSE
, /* pc_relative */
850 complain_overflow_dont
, /* complain_on_overflow */
851 _bfd_mips_elf_generic_reloc
, /* special_function */
852 "R_MIPS_REL32", /* name */
853 FALSE
, /* partial_inplace */
855 0xffffffff, /* dst_mask */
856 FALSE
), /* pcrel_offset */
858 /* 26 bit jump address. */
859 HOWTO (R_MIPS_26
, /* type */
861 2, /* size (0 = byte, 1 = short, 2 = long) */
863 FALSE
, /* pc_relative */
865 complain_overflow_dont
, /* complain_on_overflow */
866 /* This needs complex overflow
867 detection, because the upper 36
868 bits must match the PC + 4. */
869 _bfd_mips_elf_generic_reloc
, /* special_function */
870 "R_MIPS_26", /* name */
871 FALSE
, /* partial_inplace */
873 0x03ffffff, /* dst_mask */
874 FALSE
), /* pcrel_offset */
876 /* High 16 bits of symbol value. */
877 HOWTO (R_MIPS_HI16
, /* type */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
881 FALSE
, /* pc_relative */
883 complain_overflow_dont
, /* complain_on_overflow */
884 _bfd_mips_elf_generic_reloc
, /* special_function */
885 "R_MIPS_HI16", /* name */
886 FALSE
, /* partial_inplace */
888 0x0000ffff, /* dst_mask */
889 FALSE
), /* pcrel_offset */
891 /* Low 16 bits of symbol value. */
892 HOWTO (R_MIPS_LO16
, /* type */
894 2, /* size (0 = byte, 1 = short, 2 = long) */
896 FALSE
, /* pc_relative */
898 complain_overflow_dont
, /* complain_on_overflow */
899 _bfd_mips_elf_generic_reloc
, /* special_function */
900 "R_MIPS_LO16", /* name */
901 FALSE
, /* partial_inplace */
903 0x0000ffff, /* dst_mask */
904 FALSE
), /* pcrel_offset */
906 /* GP relative reference. */
907 HOWTO (R_MIPS_GPREL16
, /* type */
909 2, /* size (0 = byte, 1 = short, 2 = long) */
911 FALSE
, /* pc_relative */
913 complain_overflow_signed
, /* complain_on_overflow */
914 mips_elf64_gprel16_reloc
, /* special_function */
915 "R_MIPS_GPREL16", /* name */
916 FALSE
, /* partial_inplace */
918 0x0000ffff, /* dst_mask */
919 FALSE
), /* pcrel_offset */
921 /* Reference to literal section. */
922 HOWTO (R_MIPS_LITERAL
, /* type */
924 2, /* size (0 = byte, 1 = short, 2 = long) */
926 FALSE
, /* pc_relative */
928 complain_overflow_signed
, /* complain_on_overflow */
929 mips_elf64_literal_reloc
, /* special_function */
930 "R_MIPS_LITERAL", /* name */
931 FALSE
, /* partial_inplace */
933 0x0000ffff, /* dst_mask */
934 FALSE
), /* pcrel_offset */
936 /* Reference to global offset table. */
937 HOWTO (R_MIPS_GOT16
, /* type */
939 2, /* size (0 = byte, 1 = short, 2 = long) */
941 FALSE
, /* pc_relative */
943 complain_overflow_signed
, /* complain_on_overflow */
944 _bfd_mips_elf_generic_reloc
, /* special_function */
945 "R_MIPS_GOT16", /* name */
946 FALSE
, /* partial_inplace */
948 0x0000ffff, /* dst_mask */
949 FALSE
), /* pcrel_offset */
951 /* 16 bit PC relative reference. */
952 HOWTO (R_MIPS_PC16
, /* type */
954 2, /* size (0 = byte, 1 = short, 2 = long) */
956 TRUE
, /* pc_relative */
958 complain_overflow_signed
, /* complain_on_overflow */
959 _bfd_mips_elf_generic_reloc
, /* special_function */
960 "R_MIPS_PC16", /* name */
961 FALSE
, /* partial_inplace */
963 0x0000ffff, /* dst_mask */
964 TRUE
), /* pcrel_offset */
966 /* 16 bit call through global offset table. */
967 HOWTO (R_MIPS_CALL16
, /* type */
969 2, /* size (0 = byte, 1 = short, 2 = long) */
971 FALSE
, /* pc_relative */
973 complain_overflow_signed
, /* complain_on_overflow */
974 _bfd_mips_elf_generic_reloc
, /* special_function */
975 "R_MIPS_CALL16", /* name */
976 FALSE
, /* partial_inplace */
978 0x0000ffff, /* dst_mask */
979 FALSE
), /* pcrel_offset */
981 /* 32 bit GP relative reference. */
982 HOWTO (R_MIPS_GPREL32
, /* type */
984 2, /* size (0 = byte, 1 = short, 2 = long) */
986 FALSE
, /* pc_relative */
988 complain_overflow_dont
, /* complain_on_overflow */
989 mips_elf64_gprel32_reloc
, /* special_function */
990 "R_MIPS_GPREL32", /* name */
991 FALSE
, /* partial_inplace */
993 0xffffffff, /* dst_mask */
994 FALSE
), /* pcrel_offset */
1000 /* A 5 bit shift field. */
1001 HOWTO (R_MIPS_SHIFT5
, /* type */
1003 2, /* size (0 = byte, 1 = short, 2 = long) */
1005 FALSE
, /* pc_relative */
1007 complain_overflow_bitfield
, /* complain_on_overflow */
1008 _bfd_mips_elf_generic_reloc
, /* special_function */
1009 "R_MIPS_SHIFT5", /* name */
1010 FALSE
, /* partial_inplace */
1012 0x000007c0, /* dst_mask */
1013 FALSE
), /* pcrel_offset */
1015 /* A 6 bit shift field. */
1016 HOWTO (R_MIPS_SHIFT6
, /* type */
1018 2, /* size (0 = byte, 1 = short, 2 = long) */
1020 FALSE
, /* pc_relative */
1022 complain_overflow_bitfield
, /* complain_on_overflow */
1023 mips_elf64_shift6_reloc
, /* special_function */
1024 "R_MIPS_SHIFT6", /* name */
1025 FALSE
, /* partial_inplace */
1027 0x000007c4, /* dst_mask */
1028 FALSE
), /* pcrel_offset */
1030 /* 64 bit relocation. */
1031 HOWTO (R_MIPS_64
, /* type */
1033 4, /* size (0 = byte, 1 = short, 2 = long) */
1035 FALSE
, /* pc_relative */
1037 complain_overflow_dont
, /* complain_on_overflow */
1038 _bfd_mips_elf_generic_reloc
, /* special_function */
1039 "R_MIPS_64", /* name */
1040 FALSE
, /* partial_inplace */
1042 MINUS_ONE
, /* dst_mask */
1043 FALSE
), /* pcrel_offset */
1045 /* Displacement in the global offset table. */
1046 HOWTO (R_MIPS_GOT_DISP
, /* type */
1048 2, /* size (0 = byte, 1 = short, 2 = long) */
1050 FALSE
, /* pc_relative */
1052 complain_overflow_signed
, /* complain_on_overflow */
1053 _bfd_mips_elf_generic_reloc
, /* special_function */
1054 "R_MIPS_GOT_DISP", /* name */
1055 FALSE
, /* partial_inplace */
1057 0x0000ffff, /* dst_mask */
1058 FALSE
), /* pcrel_offset */
1060 /* Displacement to page pointer in the global offset table. */
1061 HOWTO (R_MIPS_GOT_PAGE
, /* type */
1063 2, /* size (0 = byte, 1 = short, 2 = long) */
1065 FALSE
, /* pc_relative */
1067 complain_overflow_signed
, /* complain_on_overflow */
1068 _bfd_mips_elf_generic_reloc
, /* special_function */
1069 "R_MIPS_GOT_PAGE", /* name */
1070 FALSE
, /* partial_inplace */
1072 0x0000ffff, /* dst_mask */
1073 FALSE
), /* pcrel_offset */
1075 /* Offset from page pointer in the global offset table. */
1076 HOWTO (R_MIPS_GOT_OFST
, /* type */
1078 2, /* size (0 = byte, 1 = short, 2 = long) */
1080 FALSE
, /* pc_relative */
1082 complain_overflow_signed
, /* complain_on_overflow */
1083 _bfd_mips_elf_generic_reloc
, /* special_function */
1084 "R_MIPS_GOT_OFST", /* name */
1085 FALSE
, /* partial_inplace */
1087 0x0000ffff, /* dst_mask */
1088 FALSE
), /* pcrel_offset */
1090 /* High 16 bits of displacement in global offset table. */
1091 HOWTO (R_MIPS_GOT_HI16
, /* type */
1093 2, /* size (0 = byte, 1 = short, 2 = long) */
1095 FALSE
, /* pc_relative */
1097 complain_overflow_dont
, /* complain_on_overflow */
1098 _bfd_mips_elf_generic_reloc
, /* special_function */
1099 "R_MIPS_GOT_HI16", /* name */
1100 FALSE
, /* partial_inplace */
1102 0x0000ffff, /* dst_mask */
1103 FALSE
), /* pcrel_offset */
1105 /* Low 16 bits of displacement in global offset table. */
1106 HOWTO (R_MIPS_GOT_LO16
, /* type */
1108 2, /* size (0 = byte, 1 = short, 2 = long) */
1110 FALSE
, /* pc_relative */
1112 complain_overflow_dont
, /* complain_on_overflow */
1113 _bfd_mips_elf_generic_reloc
, /* special_function */
1114 "R_MIPS_GOT_LO16", /* name */
1115 FALSE
, /* partial_inplace */
1117 0x0000ffff, /* dst_mask */
1118 FALSE
), /* pcrel_offset */
1120 /* 64 bit subtraction. */
1121 HOWTO (R_MIPS_SUB
, /* type */
1123 4, /* size (0 = byte, 1 = short, 2 = long) */
1125 FALSE
, /* pc_relative */
1127 complain_overflow_dont
, /* complain_on_overflow */
1128 _bfd_mips_elf_generic_reloc
, /* special_function */
1129 "R_MIPS_SUB", /* name */
1130 FALSE
, /* partial_inplace */
1132 MINUS_ONE
, /* dst_mask */
1133 FALSE
), /* pcrel_offset */
1135 /* Insert the addend as an instruction. */
1136 /* FIXME: Not handled correctly. */
1137 HOWTO (R_MIPS_INSERT_A
, /* type */
1139 2, /* size (0 = byte, 1 = short, 2 = long) */
1141 FALSE
, /* pc_relative */
1143 complain_overflow_dont
, /* complain_on_overflow */
1144 _bfd_mips_elf_generic_reloc
, /* special_function */
1145 "R_MIPS_INSERT_A", /* name */
1146 FALSE
, /* partial_inplace */
1148 0xffffffff, /* dst_mask */
1149 FALSE
), /* pcrel_offset */
1151 /* Insert the addend as an instruction, and change all relocations
1152 to refer to the old instruction at the address. */
1153 /* FIXME: Not handled correctly. */
1154 HOWTO (R_MIPS_INSERT_B
, /* type */
1156 2, /* size (0 = byte, 1 = short, 2 = long) */
1158 FALSE
, /* pc_relative */
1160 complain_overflow_dont
, /* complain_on_overflow */
1161 _bfd_mips_elf_generic_reloc
, /* special_function */
1162 "R_MIPS_INSERT_B", /* name */
1163 FALSE
, /* partial_inplace */
1165 0xffffffff, /* dst_mask */
1166 FALSE
), /* pcrel_offset */
1168 /* Delete a 32 bit instruction. */
1169 /* FIXME: Not handled correctly. */
1170 HOWTO (R_MIPS_DELETE
, /* type */
1172 2, /* size (0 = byte, 1 = short, 2 = long) */
1174 FALSE
, /* pc_relative */
1176 complain_overflow_dont
, /* complain_on_overflow */
1177 _bfd_mips_elf_generic_reloc
, /* special_function */
1178 "R_MIPS_DELETE", /* name */
1179 FALSE
, /* partial_inplace */
1181 0xffffffff, /* dst_mask */
1182 FALSE
), /* pcrel_offset */
1184 /* Get the higher value of a 64 bit addend. */
1185 HOWTO (R_MIPS_HIGHER
, /* type */
1187 2, /* size (0 = byte, 1 = short, 2 = long) */
1189 FALSE
, /* pc_relative */
1191 complain_overflow_dont
, /* complain_on_overflow */
1192 _bfd_mips_elf_generic_reloc
, /* special_function */
1193 "R_MIPS_HIGHER", /* name */
1194 FALSE
, /* partial_inplace */
1196 0x0000ffff, /* dst_mask */
1197 FALSE
), /* pcrel_offset */
1199 /* Get the highest value of a 64 bit addend. */
1200 HOWTO (R_MIPS_HIGHEST
, /* type */
1202 2, /* size (0 = byte, 1 = short, 2 = long) */
1204 FALSE
, /* pc_relative */
1206 complain_overflow_dont
, /* complain_on_overflow */
1207 _bfd_mips_elf_generic_reloc
, /* special_function */
1208 "R_MIPS_HIGHEST", /* name */
1209 FALSE
, /* partial_inplace */
1211 0x0000ffff, /* dst_mask */
1212 FALSE
), /* pcrel_offset */
1214 /* High 16 bits of displacement in global offset table. */
1215 HOWTO (R_MIPS_CALL_HI16
, /* type */
1217 2, /* size (0 = byte, 1 = short, 2 = long) */
1219 FALSE
, /* pc_relative */
1221 complain_overflow_dont
, /* complain_on_overflow */
1222 _bfd_mips_elf_generic_reloc
, /* special_function */
1223 "R_MIPS_CALL_HI16", /* name */
1224 FALSE
, /* partial_inplace */
1226 0x0000ffff, /* dst_mask */
1227 FALSE
), /* pcrel_offset */
1229 /* Low 16 bits of displacement in global offset table. */
1230 HOWTO (R_MIPS_CALL_LO16
, /* type */
1232 2, /* size (0 = byte, 1 = short, 2 = long) */
1234 FALSE
, /* pc_relative */
1236 complain_overflow_dont
, /* complain_on_overflow */
1237 _bfd_mips_elf_generic_reloc
, /* special_function */
1238 "R_MIPS_CALL_LO16", /* name */
1239 FALSE
, /* partial_inplace */
1241 0x0000ffff, /* dst_mask */
1242 FALSE
), /* pcrel_offset */
1244 /* Section displacement, used by an associated event location section. */
1245 HOWTO (R_MIPS_SCN_DISP
, /* type */
1247 2, /* size (0 = byte, 1 = short, 2 = long) */
1249 FALSE
, /* pc_relative */
1251 complain_overflow_dont
, /* complain_on_overflow */
1252 _bfd_mips_elf_generic_reloc
, /* special_function */
1253 "R_MIPS_SCN_DISP", /* name */
1254 FALSE
, /* partial_inplace */
1256 0xffffffff, /* dst_mask */
1257 FALSE
), /* pcrel_offset */
1259 HOWTO (R_MIPS_REL16
, /* type */
1261 1, /* size (0 = byte, 1 = short, 2 = long) */
1263 FALSE
, /* pc_relative */
1265 complain_overflow_signed
, /* complain_on_overflow */
1266 _bfd_mips_elf_generic_reloc
, /* special_function */
1267 "R_MIPS_REL16", /* name */
1268 FALSE
, /* partial_inplace */
1270 0xffff, /* dst_mask */
1271 FALSE
), /* pcrel_offset */
1273 /* These two are obsolete. */
1274 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
1275 EMPTY_HOWTO (R_MIPS_PJUMP
),
1277 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1278 It must be used for multigot GOT's (and only there). */
1279 HOWTO (R_MIPS_RELGOT
, /* type */
1281 2, /* size (0 = byte, 1 = short, 2 = long) */
1283 FALSE
, /* pc_relative */
1285 complain_overflow_dont
, /* complain_on_overflow */
1286 _bfd_mips_elf_generic_reloc
, /* special_function */
1287 "R_MIPS_RELGOT", /* name */
1288 FALSE
, /* partial_inplace */
1290 0xffffffff, /* dst_mask */
1291 FALSE
), /* pcrel_offset */
1293 /* Protected jump conversion. This is an optimization hint. No
1294 relocation is required for correctness. */
1295 HOWTO (R_MIPS_JALR
, /* type */
1297 2, /* size (0 = byte, 1 = short, 2 = long) */
1299 FALSE
, /* pc_relative */
1301 complain_overflow_dont
, /* complain_on_overflow */
1302 _bfd_mips_elf_generic_reloc
, /* special_function */
1303 "R_MIPS_JALR", /* name */
1304 FALSE
, /* partial_inplace */
1306 0x00000000, /* dst_mask */
1307 FALSE
), /* pcrel_offset */
1309 /* TLS relocations. */
1310 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32
),
1311 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32
),
1312 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64
),
1313 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64
),
1315 /* TLS general dynamic variable reference. */
1316 HOWTO (R_MIPS_TLS_GD
, /* type */
1318 2, /* size (0 = byte, 1 = short, 2 = long) */
1320 FALSE
, /* pc_relative */
1322 complain_overflow_signed
, /* complain_on_overflow */
1323 _bfd_mips_elf_generic_reloc
, /* special_function */
1324 "R_MIPS_TLS_GD", /* name */
1325 TRUE
, /* partial_inplace */
1326 0x0000ffff, /* src_mask */
1327 0x0000ffff, /* dst_mask */
1328 FALSE
), /* pcrel_offset */
1330 /* TLS local dynamic variable reference. */
1331 HOWTO (R_MIPS_TLS_LDM
, /* type */
1333 2, /* size (0 = byte, 1 = short, 2 = long) */
1335 FALSE
, /* pc_relative */
1337 complain_overflow_signed
, /* complain_on_overflow */
1338 _bfd_mips_elf_generic_reloc
, /* special_function */
1339 "R_MIPS_TLS_LDM", /* name */
1340 TRUE
, /* partial_inplace */
1341 0x0000ffff, /* src_mask */
1342 0x0000ffff, /* dst_mask */
1343 FALSE
), /* pcrel_offset */
1345 /* TLS local dynamic offset. */
1346 HOWTO (R_MIPS_TLS_DTPREL_HI16
, /* type */
1348 2, /* size (0 = byte, 1 = short, 2 = long) */
1350 FALSE
, /* pc_relative */
1352 complain_overflow_signed
, /* complain_on_overflow */
1353 _bfd_mips_elf_generic_reloc
, /* special_function */
1354 "R_MIPS_TLS_DTPREL_HI16", /* name */
1355 TRUE
, /* partial_inplace */
1356 0x0000ffff, /* src_mask */
1357 0x0000ffff, /* dst_mask */
1358 FALSE
), /* pcrel_offset */
1360 /* TLS local dynamic offset. */
1361 HOWTO (R_MIPS_TLS_DTPREL_LO16
, /* type */
1363 2, /* size (0 = byte, 1 = short, 2 = long) */
1365 FALSE
, /* pc_relative */
1367 complain_overflow_signed
, /* complain_on_overflow */
1368 _bfd_mips_elf_generic_reloc
, /* special_function */
1369 "R_MIPS_TLS_DTPREL_LO16", /* name */
1370 TRUE
, /* partial_inplace */
1371 0x0000ffff, /* src_mask */
1372 0x0000ffff, /* dst_mask */
1373 FALSE
), /* pcrel_offset */
1375 /* TLS thread pointer offset. */
1376 HOWTO (R_MIPS_TLS_GOTTPREL
, /* type */
1378 2, /* size (0 = byte, 1 = short, 2 = long) */
1380 FALSE
, /* pc_relative */
1382 complain_overflow_signed
, /* complain_on_overflow */
1383 _bfd_mips_elf_generic_reloc
, /* special_function */
1384 "R_MIPS_TLS_GOTTPREL", /* name */
1385 TRUE
, /* partial_inplace */
1386 0x0000ffff, /* src_mask */
1387 0x0000ffff, /* dst_mask */
1388 FALSE
), /* pcrel_offset */
1390 EMPTY_HOWTO (R_MIPS_TLS_TPREL32
),
1391 EMPTY_HOWTO (R_MIPS_TLS_TPREL64
),
1393 /* TLS thread pointer offset. */
1394 HOWTO (R_MIPS_TLS_TPREL_HI16
, /* type */
1396 2, /* size (0 = byte, 1 = short, 2 = long) */
1398 FALSE
, /* pc_relative */
1400 complain_overflow_signed
, /* complain_on_overflow */
1401 _bfd_mips_elf_generic_reloc
, /* special_function */
1402 "R_MIPS_TLS_TPREL_HI16", /* name */
1403 TRUE
, /* partial_inplace */
1404 0x0000ffff, /* src_mask */
1405 0x0000ffff, /* dst_mask */
1406 FALSE
), /* pcrel_offset */
1408 /* TLS thread pointer offset. */
1409 HOWTO (R_MIPS_TLS_TPREL_LO16
, /* type */
1411 2, /* size (0 = byte, 1 = short, 2 = long) */
1413 FALSE
, /* pc_relative */
1415 complain_overflow_signed
, /* complain_on_overflow */
1416 _bfd_mips_elf_generic_reloc
, /* special_function */
1417 "R_MIPS_TLS_TPREL_LO16", /* name */
1418 TRUE
, /* partial_inplace */
1419 0x0000ffff, /* src_mask */
1420 0x0000ffff, /* dst_mask */
1421 FALSE
), /* pcrel_offset */
1424 static reloc_howto_type mips16_elf64_howto_table_rel
[] =
1426 /* The reloc used for the mips16 jump instruction. */
1427 HOWTO (R_MIPS16_26
, /* type */
1429 2, /* size (0 = byte, 1 = short, 2 = long) */
1431 FALSE
, /* pc_relative */
1433 complain_overflow_dont
, /* complain_on_overflow */
1434 /* This needs complex overflow
1435 detection, because the upper four
1436 bits must match the PC. */
1437 mips16_jump_reloc
, /* special_function */
1438 "R_MIPS16_26", /* name */
1439 TRUE
, /* partial_inplace */
1440 0x3ffffff, /* src_mask */
1441 0x3ffffff, /* dst_mask */
1442 FALSE
), /* pcrel_offset */
1444 /* The reloc used for the mips16 gprel instruction. */
1445 HOWTO (R_MIPS16_GPREL
, /* type */
1447 2, /* size (0 = byte, 1 = short, 2 = long) */
1449 FALSE
, /* pc_relative */
1451 complain_overflow_signed
, /* complain_on_overflow */
1452 mips16_gprel_reloc
, /* special_function */
1453 "R_MIPS16_GPREL", /* name */
1454 TRUE
, /* partial_inplace */
1455 0x0000ffff, /* src_mask */
1456 0x0000ffff, /* dst_mask */
1457 FALSE
), /* pcrel_offset */
1459 /* A placeholder for MIPS16 reference to global offset table. */
1460 EMPTY_HOWTO (R_MIPS16_GOT16
),
1462 /* A placeholder for MIPS16 16 bit call through global offset table. */
1463 EMPTY_HOWTO (R_MIPS16_CALL16
),
1465 /* MIPS16 high 16 bits of symbol value. */
1466 HOWTO (R_MIPS16_HI16
, /* type */
1467 16, /* rightshift */
1468 2, /* size (0 = byte, 1 = short, 2 = long) */
1470 FALSE
, /* pc_relative */
1472 complain_overflow_dont
, /* complain_on_overflow */
1473 _bfd_mips_elf_hi16_reloc
, /* special_function */
1474 "R_MIPS16_HI16", /* name */
1475 TRUE
, /* partial_inplace */
1476 0x0000ffff, /* src_mask */
1477 0x0000ffff, /* dst_mask */
1478 FALSE
), /* pcrel_offset */
1480 /* MIPS16 low 16 bits of symbol value. */
1481 HOWTO (R_MIPS16_LO16
, /* type */
1483 2, /* size (0 = byte, 1 = short, 2 = long) */
1485 FALSE
, /* pc_relative */
1487 complain_overflow_dont
, /* complain_on_overflow */
1488 _bfd_mips_elf_lo16_reloc
, /* special_function */
1489 "R_MIPS16_LO16", /* name */
1490 TRUE
, /* partial_inplace */
1491 0x0000ffff, /* src_mask */
1492 0x0000ffff, /* dst_mask */
1493 FALSE
), /* pcrel_offset */
1496 static reloc_howto_type mips16_elf64_howto_table_rela
[] =
1498 /* The reloc used for the mips16 jump instruction. */
1499 HOWTO (R_MIPS16_26
, /* type */
1501 2, /* size (0 = byte, 1 = short, 2 = long) */
1503 FALSE
, /* pc_relative */
1505 complain_overflow_dont
, /* complain_on_overflow */
1506 /* This needs complex overflow
1507 detection, because the upper four
1508 bits must match the PC. */
1509 mips16_jump_reloc
, /* special_function */
1510 "R_MIPS16_26", /* name */
1511 FALSE
, /* partial_inplace */
1512 0x3ffffff, /* src_mask */
1513 0x3ffffff, /* dst_mask */
1514 FALSE
), /* pcrel_offset */
1516 /* The reloc used for the mips16 gprel instruction. */
1517 HOWTO (R_MIPS16_GPREL
, /* type */
1519 2, /* size (0 = byte, 1 = short, 2 = long) */
1521 FALSE
, /* pc_relative */
1523 complain_overflow_signed
, /* complain_on_overflow */
1524 mips16_gprel_reloc
, /* special_function */
1525 "R_MIPS16_GPREL", /* name */
1526 FALSE
, /* partial_inplace */
1527 0x0000ffff, /* src_mask */
1528 0x0000ffff, /* dst_mask */
1529 FALSE
), /* pcrel_offset */
1531 /* A placeholder for MIPS16 reference to global offset table. */
1532 EMPTY_HOWTO (R_MIPS16_GOT16
),
1534 /* A placeholder for MIPS16 16 bit call through global offset table. */
1535 EMPTY_HOWTO (R_MIPS16_CALL16
),
1537 /* MIPS16 high 16 bits of symbol value. */
1538 HOWTO (R_MIPS16_HI16
, /* type */
1539 16, /* rightshift */
1540 2, /* size (0 = byte, 1 = short, 2 = long) */
1542 FALSE
, /* pc_relative */
1544 complain_overflow_dont
, /* complain_on_overflow */
1545 _bfd_mips_elf_hi16_reloc
, /* special_function */
1546 "R_MIPS16_HI16", /* name */
1547 FALSE
, /* partial_inplace */
1548 0x0000ffff, /* src_mask */
1549 0x0000ffff, /* dst_mask */
1550 FALSE
), /* pcrel_offset */
1552 /* MIPS16 low 16 bits of symbol value. */
1553 HOWTO (R_MIPS16_LO16
, /* type */
1555 2, /* size (0 = byte, 1 = short, 2 = long) */
1557 FALSE
, /* pc_relative */
1559 complain_overflow_dont
, /* complain_on_overflow */
1560 _bfd_mips_elf_lo16_reloc
, /* special_function */
1561 "R_MIPS16_LO16", /* name */
1562 FALSE
, /* partial_inplace */
1563 0x0000ffff, /* src_mask */
1564 0x0000ffff, /* dst_mask */
1565 FALSE
), /* pcrel_offset */
1568 /* GNU extension to record C++ vtable hierarchy */
1569 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
1570 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
1572 2, /* size (0 = byte, 1 = short, 2 = long) */
1574 FALSE
, /* pc_relative */
1576 complain_overflow_dont
, /* complain_on_overflow */
1577 NULL
, /* special_function */
1578 "R_MIPS_GNU_VTINHERIT", /* name */
1579 FALSE
, /* partial_inplace */
1582 FALSE
); /* pcrel_offset */
1584 /* GNU extension to record C++ vtable member usage */
1585 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
1586 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
1588 2, /* size (0 = byte, 1 = short, 2 = long) */
1590 FALSE
, /* pc_relative */
1592 complain_overflow_dont
, /* complain_on_overflow */
1593 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
1594 "R_MIPS_GNU_VTENTRY", /* name */
1595 FALSE
, /* partial_inplace */
1598 FALSE
); /* pcrel_offset */
1600 /* 16 bit offset for pc-relative branches. */
1601 static reloc_howto_type elf_mips_gnu_rel16_s2
=
1602 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1604 2, /* size (0 = byte, 1 = short, 2 = long) */
1606 TRUE
, /* pc_relative */
1608 complain_overflow_signed
, /* complain_on_overflow */
1609 _bfd_mips_elf_generic_reloc
, /* special_function */
1610 "R_MIPS_GNU_REL16_S2", /* name */
1611 TRUE
, /* partial_inplace */
1612 0x0000ffff, /* src_mask */
1613 0x0000ffff, /* dst_mask */
1614 TRUE
); /* pcrel_offset */
1616 /* 16 bit offset for pc-relative branches. */
1617 static reloc_howto_type elf_mips_gnu_rela16_s2
=
1618 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
1620 2, /* size (0 = byte, 1 = short, 2 = long) */
1622 TRUE
, /* pc_relative */
1624 complain_overflow_signed
, /* complain_on_overflow */
1625 _bfd_mips_elf_generic_reloc
, /* special_function */
1626 "R_MIPS_GNU_REL16_S2", /* name */
1627 FALSE
, /* partial_inplace */
1629 0x0000ffff, /* dst_mask */
1630 TRUE
); /* pcrel_offset */
1632 /* Swap in a MIPS 64-bit Rel reloc. */
1635 mips_elf64_swap_reloc_in (bfd
*abfd
, const Elf64_Mips_External_Rel
*src
,
1636 Elf64_Mips_Internal_Rela
*dst
)
1638 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1639 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1640 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1641 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1642 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1643 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1647 /* Swap in a MIPS 64-bit Rela reloc. */
1650 mips_elf64_swap_reloca_in (bfd
*abfd
, const Elf64_Mips_External_Rela
*src
,
1651 Elf64_Mips_Internal_Rela
*dst
)
1653 dst
->r_offset
= H_GET_64 (abfd
, src
->r_offset
);
1654 dst
->r_sym
= H_GET_32 (abfd
, src
->r_sym
);
1655 dst
->r_ssym
= H_GET_8 (abfd
, src
->r_ssym
);
1656 dst
->r_type3
= H_GET_8 (abfd
, src
->r_type3
);
1657 dst
->r_type2
= H_GET_8 (abfd
, src
->r_type2
);
1658 dst
->r_type
= H_GET_8 (abfd
, src
->r_type
);
1659 dst
->r_addend
= H_GET_S64 (abfd
, src
->r_addend
);
1662 /* Swap out a MIPS 64-bit Rel reloc. */
1665 mips_elf64_swap_reloc_out (bfd
*abfd
, const Elf64_Mips_Internal_Rela
*src
,
1666 Elf64_Mips_External_Rel
*dst
)
1668 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1669 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1670 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1671 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1672 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1673 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1676 /* Swap out a MIPS 64-bit Rela reloc. */
1679 mips_elf64_swap_reloca_out (bfd
*abfd
, const Elf64_Mips_Internal_Rela
*src
,
1680 Elf64_Mips_External_Rela
*dst
)
1682 H_PUT_64 (abfd
, src
->r_offset
, dst
->r_offset
);
1683 H_PUT_32 (abfd
, src
->r_sym
, dst
->r_sym
);
1684 H_PUT_8 (abfd
, src
->r_ssym
, dst
->r_ssym
);
1685 H_PUT_8 (abfd
, src
->r_type3
, dst
->r_type3
);
1686 H_PUT_8 (abfd
, src
->r_type2
, dst
->r_type2
);
1687 H_PUT_8 (abfd
, src
->r_type
, dst
->r_type
);
1688 H_PUT_S64 (abfd
, src
->r_addend
, dst
->r_addend
);
1691 /* Swap in a MIPS 64-bit Rel reloc. */
1694 mips_elf64_be_swap_reloc_in (bfd
*abfd
, const bfd_byte
*src
,
1695 Elf_Internal_Rela
*dst
)
1697 Elf64_Mips_Internal_Rela mirel
;
1699 mips_elf64_swap_reloc_in (abfd
,
1700 (const Elf64_Mips_External_Rel
*) src
,
1703 dst
[0].r_offset
= mirel
.r_offset
;
1704 dst
[0].r_info
= ELF64_R_INFO (mirel
.r_sym
, mirel
.r_type
);
1705 dst
[0].r_addend
= 0;
1706 dst
[1].r_offset
= mirel
.r_offset
;
1707 dst
[1].r_info
= ELF64_R_INFO (mirel
.r_ssym
, mirel
.r_type2
);
1708 dst
[1].r_addend
= 0;
1709 dst
[2].r_offset
= mirel
.r_offset
;
1710 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirel
.r_type3
);
1711 dst
[2].r_addend
= 0;
1714 /* Swap in a MIPS 64-bit Rela reloc. */
1717 mips_elf64_be_swap_reloca_in (bfd
*abfd
, const bfd_byte
*src
,
1718 Elf_Internal_Rela
*dst
)
1720 Elf64_Mips_Internal_Rela mirela
;
1722 mips_elf64_swap_reloca_in (abfd
,
1723 (const Elf64_Mips_External_Rela
*) src
,
1726 dst
[0].r_offset
= mirela
.r_offset
;
1727 dst
[0].r_info
= ELF64_R_INFO (mirela
.r_sym
, mirela
.r_type
);
1728 dst
[0].r_addend
= mirela
.r_addend
;
1729 dst
[1].r_offset
= mirela
.r_offset
;
1730 dst
[1].r_info
= ELF64_R_INFO (mirela
.r_ssym
, mirela
.r_type2
);
1731 dst
[1].r_addend
= 0;
1732 dst
[2].r_offset
= mirela
.r_offset
;
1733 dst
[2].r_info
= ELF64_R_INFO (STN_UNDEF
, mirela
.r_type3
);
1734 dst
[2].r_addend
= 0;
1737 /* Swap out a MIPS 64-bit Rel reloc. */
1740 mips_elf64_be_swap_reloc_out (bfd
*abfd
, const Elf_Internal_Rela
*src
,
1743 Elf64_Mips_Internal_Rela mirel
;
1745 mirel
.r_offset
= src
[0].r_offset
;
1746 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1748 mirel
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1749 mirel
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1750 mirel
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1751 mirel
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1752 mirel
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1754 mips_elf64_swap_reloc_out (abfd
, &mirel
,
1755 (Elf64_Mips_External_Rel
*) dst
);
1758 /* Swap out a MIPS 64-bit Rela reloc. */
1761 mips_elf64_be_swap_reloca_out (bfd
*abfd
, const Elf_Internal_Rela
*src
,
1764 Elf64_Mips_Internal_Rela mirela
;
1766 mirela
.r_offset
= src
[0].r_offset
;
1767 BFD_ASSERT(src
[0].r_offset
== src
[1].r_offset
);
1768 BFD_ASSERT(src
[0].r_offset
== src
[2].r_offset
);
1770 mirela
.r_type
= ELF64_MIPS_R_TYPE (src
[0].r_info
);
1771 mirela
.r_sym
= ELF64_R_SYM (src
[0].r_info
);
1772 mirela
.r_addend
= src
[0].r_addend
;
1773 BFD_ASSERT(src
[1].r_addend
== 0);
1774 BFD_ASSERT(src
[2].r_addend
== 0);
1776 mirela
.r_type2
= ELF64_MIPS_R_TYPE (src
[1].r_info
);
1777 mirela
.r_ssym
= ELF64_MIPS_R_SSYM (src
[1].r_info
);
1778 mirela
.r_type3
= ELF64_MIPS_R_TYPE (src
[2].r_info
);
1780 mips_elf64_swap_reloca_out (abfd
, &mirela
,
1781 (Elf64_Mips_External_Rela
*) dst
);
1784 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1785 dangerous relocation. */
1788 mips_elf64_assign_gp (bfd
*output_bfd
, bfd_vma
*pgp
)
1794 /* If we've already figured out what GP will be, just return it. */
1795 *pgp
= _bfd_get_gp_value (output_bfd
);
1799 count
= bfd_get_symcount (output_bfd
);
1800 sym
= bfd_get_outsymbols (output_bfd
);
1802 /* The linker script will have created a symbol named `_gp' with the
1803 appropriate value. */
1808 for (i
= 0; i
< count
; i
++, sym
++)
1810 register const char *name
;
1812 name
= bfd_asymbol_name (*sym
);
1813 if (*name
== '_' && strcmp (name
, "_gp") == 0)
1815 *pgp
= bfd_asymbol_value (*sym
);
1816 _bfd_set_gp_value (output_bfd
, *pgp
);
1824 /* Only get the error once. */
1826 _bfd_set_gp_value (output_bfd
, *pgp
);
1833 /* We have to figure out the gp value, so that we can adjust the
1834 symbol value correctly. We look up the symbol _gp in the output
1835 BFD. If we can't find it, we're stuck. We cache it in the ELF
1836 target data. We don't need to adjust the symbol value for an
1837 external symbol if we are producing relocatable output. */
1839 static bfd_reloc_status_type
1840 mips_elf64_final_gp (bfd
*output_bfd
, asymbol
*symbol
, bfd_boolean relocatable
,
1841 char **error_message
, bfd_vma
*pgp
)
1843 if (bfd_is_und_section (symbol
->section
)
1847 return bfd_reloc_undefined
;
1850 *pgp
= _bfd_get_gp_value (output_bfd
);
1853 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
1857 /* Make up a value. */
1858 *pgp
= symbol
->section
->output_section
->vma
/*+ 0x4000*/;
1859 _bfd_set_gp_value (output_bfd
, *pgp
);
1861 else if (!mips_elf64_assign_gp (output_bfd
, pgp
))
1864 (char *) _("GP relative relocation when _gp not defined");
1865 return bfd_reloc_dangerous
;
1869 return bfd_reloc_ok
;
1872 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1873 become the offset from the gp register. */
1875 static bfd_reloc_status_type
1876 mips_elf64_gprel16_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1877 void *data
, asection
*input_section
, bfd
*output_bfd
,
1878 char **error_message
)
1880 bfd_boolean relocatable
;
1881 bfd_reloc_status_type ret
;
1884 /* If we're relocating, and this is an external symbol, we don't want
1885 to change anything. */
1886 if (output_bfd
!= NULL
1887 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1888 && (symbol
->flags
& BSF_LOCAL
) != 0)
1890 reloc_entry
->address
+= input_section
->output_offset
;
1891 return bfd_reloc_ok
;
1894 if (output_bfd
!= NULL
)
1898 relocatable
= FALSE
;
1899 output_bfd
= symbol
->section
->output_section
->owner
;
1902 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
1904 if (ret
!= bfd_reloc_ok
)
1907 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1908 input_section
, relocatable
,
1912 /* Do a R_MIPS_LITERAL relocation. */
1914 static bfd_reloc_status_type
1915 mips_elf64_literal_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1916 void *data
, asection
*input_section
, bfd
*output_bfd
,
1917 char **error_message
)
1919 bfd_boolean relocatable
;
1920 bfd_reloc_status_type ret
;
1923 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
1924 if (output_bfd
!= NULL
1925 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1926 && (symbol
->flags
& BSF_LOCAL
) != 0)
1928 *error_message
= (char *)
1929 _("literal relocation occurs for an external symbol");
1930 return bfd_reloc_outofrange
;
1933 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1934 if (output_bfd
!= NULL
)
1938 relocatable
= FALSE
;
1939 output_bfd
= symbol
->section
->output_section
->owner
;
1942 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
1944 if (ret
!= bfd_reloc_ok
)
1947 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1948 input_section
, relocatable
,
1952 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1953 become the offset from the gp register. */
1955 static bfd_reloc_status_type
1956 mips_elf64_gprel32_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1957 void *data
, asection
*input_section
, bfd
*output_bfd
,
1958 char **error_message
)
1960 bfd_boolean relocatable
;
1961 bfd_reloc_status_type ret
;
1966 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1967 if (output_bfd
!= NULL
1968 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1969 && (symbol
->flags
& BSF_LOCAL
) != 0)
1971 *error_message
= (char *)
1972 _("32bits gp relative relocation occurs for an external symbol");
1973 return bfd_reloc_outofrange
;
1976 if (output_bfd
!= NULL
)
1980 relocatable
= FALSE
;
1981 output_bfd
= symbol
->section
->output_section
->owner
;
1984 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
,
1985 error_message
, &gp
);
1986 if (ret
!= bfd_reloc_ok
)
1989 if (bfd_is_com_section (symbol
->section
))
1992 relocation
= symbol
->value
;
1994 relocation
+= symbol
->section
->output_section
->vma
;
1995 relocation
+= symbol
->section
->output_offset
;
1997 if (reloc_entry
->address
> bfd_get_section_limit (abfd
, input_section
))
1998 return bfd_reloc_outofrange
;
2000 /* Set val to the offset into the section or symbol. */
2001 val
= reloc_entry
->addend
;
2003 if (reloc_entry
->howto
->partial_inplace
)
2004 val
+= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
2006 /* Adjust val for the final section location and GP value. If we
2007 are producing relocatable output, we don't want to do this for
2008 an external symbol. */
2010 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
2011 val
+= relocation
- gp
;
2013 if (reloc_entry
->howto
->partial_inplace
)
2014 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
2016 reloc_entry
->addend
= val
;
2019 reloc_entry
->address
+= input_section
->output_offset
;
2021 return bfd_reloc_ok
;
2024 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2025 the rest is at bits 6-10. The bitpos already got right by the howto. */
2027 static bfd_reloc_status_type
2028 mips_elf64_shift6_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
2029 void *data
, asection
*input_section
, bfd
*output_bfd
,
2030 char **error_message
)
2032 if (reloc_entry
->howto
->partial_inplace
)
2034 reloc_entry
->addend
= ((reloc_entry
->addend
& 0x00007c0)
2035 | (reloc_entry
->addend
& 0x00000800) >> 9);
2038 return _bfd_mips_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
2039 input_section
, output_bfd
,
2043 /* Handle a mips16 jump. */
2045 static bfd_reloc_status_type
2046 mips16_jump_reloc (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*reloc_entry
,
2047 asymbol
*symbol
, void *data ATTRIBUTE_UNUSED
,
2048 asection
*input_section
, bfd
*output_bfd
,
2049 char **error_message ATTRIBUTE_UNUSED
)
2051 if (output_bfd
!= NULL
2052 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
2053 && (! reloc_entry
->howto
->partial_inplace
2054 || reloc_entry
->addend
== 0))
2056 reloc_entry
->address
+= input_section
->output_offset
;
2057 return bfd_reloc_ok
;
2062 static bfd_boolean warned
;
2065 (*_bfd_error_handler
)
2066 (_("Linking mips16 objects into %s format is not supported"),
2067 bfd_get_target (input_section
->output_section
->owner
));
2071 return bfd_reloc_undefined
;
2074 /* Handle a mips16 GP relative reloc. */
2076 static bfd_reloc_status_type
2077 mips16_gprel_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
2078 void *data
, asection
*input_section
, bfd
*output_bfd
,
2079 char **error_message
)
2081 bfd_boolean relocatable
;
2082 bfd_reloc_status_type ret
;
2086 /* If we're relocating, and this is an external symbol, we don't want
2087 to change anything. */
2088 if (output_bfd
!= NULL
2089 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
2090 && (symbol
->flags
& BSF_LOCAL
) != 0)
2092 reloc_entry
->address
+= input_section
->output_offset
;
2093 return bfd_reloc_ok
;
2096 if (output_bfd
!= NULL
)
2100 relocatable
= FALSE
;
2101 output_bfd
= symbol
->section
->output_section
->owner
;
2104 ret
= mips_elf64_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
2106 if (ret
!= bfd_reloc_ok
)
2109 location
= (bfd_byte
*) data
+ reloc_entry
->address
;
2110 _bfd_mips16_elf_reloc_unshuffle (abfd
, reloc_entry
->howto
->type
, FALSE
,
2112 ret
= _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
2113 input_section
, relocatable
,
2115 _bfd_mips16_elf_reloc_shuffle (abfd
, reloc_entry
->howto
->type
, !relocatable
,
2121 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2123 struct elf_reloc_map
{
2124 bfd_reloc_code_real_type bfd_val
;
2125 enum elf_mips_reloc_type elf_val
;
2128 static const struct elf_reloc_map mips_reloc_map
[] =
2130 { BFD_RELOC_NONE
, R_MIPS_NONE
},
2131 { BFD_RELOC_16
, R_MIPS_16
},
2132 { BFD_RELOC_32
, R_MIPS_32
},
2133 /* There is no BFD reloc for R_MIPS_REL32. */
2134 { BFD_RELOC_64
, R_MIPS_64
},
2135 { BFD_RELOC_CTOR
, R_MIPS_64
},
2136 { BFD_RELOC_16_PCREL
, R_MIPS_PC16
},
2137 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
2138 { BFD_RELOC_LO16
, R_MIPS_LO16
},
2139 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
2140 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
2141 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
2142 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
2143 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
2144 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
2145 { BFD_RELOC_MIPS_SHIFT5
, R_MIPS_SHIFT5
},
2146 { BFD_RELOC_MIPS_SHIFT6
, R_MIPS_SHIFT6
},
2147 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
},
2148 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
2149 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
2150 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
2151 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
2152 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
2153 { BFD_RELOC_MIPS_INSERT_A
, R_MIPS_INSERT_A
},
2154 { BFD_RELOC_MIPS_INSERT_B
, R_MIPS_INSERT_B
},
2155 { BFD_RELOC_MIPS_DELETE
, R_MIPS_DELETE
},
2156 { BFD_RELOC_MIPS_HIGHEST
, R_MIPS_HIGHEST
},
2157 { BFD_RELOC_MIPS_HIGHER
, R_MIPS_HIGHER
},
2158 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
2159 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
2160 { BFD_RELOC_MIPS_SCN_DISP
, R_MIPS_SCN_DISP
},
2161 { BFD_RELOC_MIPS_REL16
, R_MIPS_REL16
},
2162 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2163 { BFD_RELOC_MIPS_RELGOT
, R_MIPS_RELGOT
},
2164 { BFD_RELOC_MIPS_JALR
, R_MIPS_JALR
},
2165 { BFD_RELOC_MIPS_TLS_DTPMOD32
, R_MIPS_TLS_DTPMOD32
},
2166 { BFD_RELOC_MIPS_TLS_DTPREL32
, R_MIPS_TLS_DTPREL32
},
2167 { BFD_RELOC_MIPS_TLS_DTPMOD64
, R_MIPS_TLS_DTPMOD64
},
2168 { BFD_RELOC_MIPS_TLS_DTPREL64
, R_MIPS_TLS_DTPREL64
},
2169 { BFD_RELOC_MIPS_TLS_GD
, R_MIPS_TLS_GD
},
2170 { BFD_RELOC_MIPS_TLS_LDM
, R_MIPS_TLS_LDM
},
2171 { BFD_RELOC_MIPS_TLS_DTPREL_HI16
, R_MIPS_TLS_DTPREL_HI16
},
2172 { BFD_RELOC_MIPS_TLS_DTPREL_LO16
, R_MIPS_TLS_DTPREL_LO16
},
2173 { BFD_RELOC_MIPS_TLS_GOTTPREL
, R_MIPS_TLS_GOTTPREL
},
2174 { BFD_RELOC_MIPS_TLS_TPREL32
, R_MIPS_TLS_TPREL32
},
2175 { BFD_RELOC_MIPS_TLS_TPREL64
, R_MIPS_TLS_TPREL64
},
2176 { BFD_RELOC_MIPS_TLS_TPREL_HI16
, R_MIPS_TLS_TPREL_HI16
},
2177 { BFD_RELOC_MIPS_TLS_TPREL_LO16
, R_MIPS_TLS_TPREL_LO16
}
2180 static const struct elf_reloc_map mips16_reloc_map
[] =
2182 { BFD_RELOC_MIPS16_JMP
, R_MIPS16_26
- R_MIPS16_min
},
2183 { BFD_RELOC_MIPS16_GPREL
, R_MIPS16_GPREL
- R_MIPS16_min
},
2184 { BFD_RELOC_MIPS16_HI16_S
, R_MIPS16_HI16
- R_MIPS16_min
},
2185 { BFD_RELOC_MIPS16_LO16
, R_MIPS16_LO16
- R_MIPS16_min
},
2188 /* Given a BFD reloc type, return a howto structure. */
2190 static reloc_howto_type
*
2191 bfd_elf64_bfd_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
2192 bfd_reloc_code_real_type code
)
2195 /* FIXME: We default to RELA here instead of choosing the right
2196 relocation variant. */
2197 reloc_howto_type
*howto_table
= mips_elf64_howto_table_rela
;
2198 reloc_howto_type
*howto16_table
= mips16_elf64_howto_table_rela
;
2200 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
2203 if (mips_reloc_map
[i
].bfd_val
== code
)
2204 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
2207 for (i
= 0; i
< sizeof (mips16_reloc_map
) / sizeof (struct elf_reloc_map
);
2210 if (mips16_reloc_map
[i
].bfd_val
== code
)
2211 return &howto16_table
[(int) mips16_reloc_map
[i
].elf_val
];
2216 case BFD_RELOC_VTABLE_INHERIT
:
2217 return &elf_mips_gnu_vtinherit_howto
;
2218 case BFD_RELOC_VTABLE_ENTRY
:
2219 return &elf_mips_gnu_vtentry_howto
;
2220 case BFD_RELOC_16_PCREL_S2
:
2221 return &elf_mips_gnu_rela16_s2
;
2223 bfd_set_error (bfd_error_bad_value
);
2228 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2230 static reloc_howto_type
*
2231 mips_elf64_rtype_to_howto (unsigned int r_type
, bfd_boolean rela_p
)
2235 case R_MIPS_GNU_VTINHERIT
:
2236 return &elf_mips_gnu_vtinherit_howto
;
2237 case R_MIPS_GNU_VTENTRY
:
2238 return &elf_mips_gnu_vtentry_howto
;
2239 case R_MIPS_GNU_REL16_S2
:
2241 return &elf_mips_gnu_rela16_s2
;
2243 return &elf_mips_gnu_rel16_s2
;
2245 if (r_type
>= R_MIPS16_min
&& r_type
< R_MIPS16_max
)
2248 return &mips16_elf64_howto_table_rela
[r_type
- R_MIPS16_min
];
2250 return &mips16_elf64_howto_table_rel
[r_type
- R_MIPS16_min
];
2252 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
2254 return &mips_elf64_howto_table_rela
[r_type
];
2256 return &mips_elf64_howto_table_rel
[r_type
];
2261 /* Prevent relocation handling by bfd for MIPS ELF64. */
2264 mips_elf64_info_to_howto_rel (bfd
*abfd ATTRIBUTE_UNUSED
,
2265 arelent
*cache_ptr ATTRIBUTE_UNUSED
,
2266 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
)
2272 mips_elf64_info_to_howto_rela (bfd
*abfd ATTRIBUTE_UNUSED
,
2273 arelent
*cache_ptr ATTRIBUTE_UNUSED
,
2274 Elf_Internal_Rela
*dst ATTRIBUTE_UNUSED
)
2279 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2280 to three relocs, we must tell the user to allocate more space. */
2283 mips_elf64_get_reloc_upper_bound (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
)
2285 return (sec
->reloc_count
* 3 + 1) * sizeof (arelent
*);
2289 mips_elf64_get_dynamic_reloc_upper_bound (bfd
*abfd
)
2291 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd
) * 3;
2294 /* We must also copy more relocations than the corresponding functions
2295 in elf.c would, so the two following functions are slightly
2296 modified from elf.c, that multiply the external relocation count by
2297 3 to obtain the internal relocation count. */
2300 mips_elf64_canonicalize_reloc (bfd
*abfd
, sec_ptr section
,
2301 arelent
**relptr
, asymbol
**symbols
)
2305 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
2307 if (! bed
->s
->slurp_reloc_table (abfd
, section
, symbols
, FALSE
))
2310 tblptr
= section
->relocation
;
2311 for (i
= 0; i
< section
->reloc_count
* 3; i
++)
2312 *relptr
++ = tblptr
++;
2316 return section
->reloc_count
* 3;
2320 mips_elf64_canonicalize_dynamic_reloc (bfd
*abfd
, arelent
**storage
,
2323 bfd_boolean (*slurp_relocs
) (bfd
*, asection
*, asymbol
**, bfd_boolean
);
2327 if (elf_dynsymtab (abfd
) == 0)
2329 bfd_set_error (bfd_error_invalid_operation
);
2333 slurp_relocs
= get_elf_backend_data (abfd
)->s
->slurp_reloc_table
;
2335 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
2337 if (elf_section_data (s
)->this_hdr
.sh_link
== elf_dynsymtab (abfd
)
2338 && (elf_section_data (s
)->this_hdr
.sh_type
== SHT_REL
2339 || elf_section_data (s
)->this_hdr
.sh_type
== SHT_RELA
))
2344 if (! (*slurp_relocs
) (abfd
, s
, syms
, TRUE
))
2346 count
= s
->size
/ elf_section_data (s
)->this_hdr
.sh_entsize
* 3;
2348 for (i
= 0; i
< count
; i
++)
2359 /* Read the relocations from one reloc section. This is mostly copied
2360 from elfcode.h, except for the changes to expand one external
2361 relocation to 3 internal ones. We must unfortunately set
2362 reloc_count to the number of external relocations, because a lot of
2363 generic code seems to depend on this. */
2366 mips_elf64_slurp_one_reloc_table (bfd
*abfd
, asection
*asect
,
2367 Elf_Internal_Shdr
*rel_hdr
,
2368 bfd_size_type reloc_count
,
2369 arelent
*relents
, asymbol
**symbols
,
2370 bfd_boolean dynamic
)
2373 bfd_byte
*native_relocs
;
2379 allocated
= bfd_malloc (rel_hdr
->sh_size
);
2380 if (allocated
== NULL
)
2383 if (bfd_seek (abfd
, rel_hdr
->sh_offset
, SEEK_SET
) != 0
2384 || (bfd_bread (allocated
, rel_hdr
->sh_size
, abfd
)
2385 != rel_hdr
->sh_size
))
2388 native_relocs
= allocated
;
2390 entsize
= rel_hdr
->sh_entsize
;
2391 BFD_ASSERT (entsize
== sizeof (Elf64_Mips_External_Rel
)
2392 || entsize
== sizeof (Elf64_Mips_External_Rela
));
2394 if (entsize
== sizeof (Elf64_Mips_External_Rel
))
2399 for (i
= 0, relent
= relents
;
2401 i
++, native_relocs
+= entsize
)
2403 Elf64_Mips_Internal_Rela rela
;
2404 bfd_boolean used_sym
, used_ssym
;
2407 if (entsize
== sizeof (Elf64_Mips_External_Rela
))
2408 mips_elf64_swap_reloca_in (abfd
,
2409 (Elf64_Mips_External_Rela
*) native_relocs
,
2412 mips_elf64_swap_reloc_in (abfd
,
2413 (Elf64_Mips_External_Rel
*) native_relocs
,
2416 /* Each entry represents exactly three actual relocations. */
2420 for (ir
= 0; ir
< 3; ir
++)
2422 enum elf_mips_reloc_type type
;
2429 type
= (enum elf_mips_reloc_type
) rela
.r_type
;
2432 type
= (enum elf_mips_reloc_type
) rela
.r_type2
;
2435 type
= (enum elf_mips_reloc_type
) rela
.r_type3
;
2439 /* Some types require symbols, whereas some do not. */
2443 case R_MIPS_LITERAL
:
2444 case R_MIPS_INSERT_A
:
2445 case R_MIPS_INSERT_B
:
2447 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2453 if (rela
.r_sym
== 0)
2454 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2459 ps
= symbols
+ rela
.r_sym
- 1;
2461 if ((s
->flags
& BSF_SECTION_SYM
) == 0)
2462 relent
->sym_ptr_ptr
= ps
;
2464 relent
->sym_ptr_ptr
= s
->section
->symbol_ptr_ptr
;
2469 else if (! used_ssym
)
2471 switch (rela
.r_ssym
)
2474 relent
->sym_ptr_ptr
=
2475 bfd_abs_section_ptr
->symbol_ptr_ptr
;
2481 /* FIXME: I think these need to be handled using
2482 special howto structures. */
2494 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
2499 /* The address of an ELF reloc is section relative for an
2500 object file, and absolute for an executable file or
2501 shared library. The address of a BFD reloc is always
2502 section relative. */
2503 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0 || dynamic
)
2504 relent
->address
= rela
.r_offset
;
2506 relent
->address
= rela
.r_offset
- asect
->vma
;
2508 relent
->addend
= rela
.r_addend
;
2510 relent
->howto
= mips_elf64_rtype_to_howto (type
, rela_p
);
2516 asect
->reloc_count
+= (relent
- relents
) / 3;
2518 if (allocated
!= NULL
)
2524 if (allocated
!= NULL
)
2529 /* Read the relocations. On Irix 6, there can be two reloc sections
2530 associated with a single data section. This is copied from
2531 elfcode.h as well, with changes as small as accounting for 3
2532 internal relocs per external reloc and resetting reloc_count to
2533 zero before processing the relocs of a section. */
2536 mips_elf64_slurp_reloc_table (bfd
*abfd
, asection
*asect
,
2537 asymbol
**symbols
, bfd_boolean dynamic
)
2539 struct bfd_elf_section_data
* const d
= elf_section_data (asect
);
2540 Elf_Internal_Shdr
*rel_hdr
;
2541 Elf_Internal_Shdr
*rel_hdr2
;
2542 bfd_size_type reloc_count
;
2543 bfd_size_type reloc_count2
;
2547 if (asect
->relocation
!= NULL
)
2552 if ((asect
->flags
& SEC_RELOC
) == 0
2553 || asect
->reloc_count
== 0)
2556 rel_hdr
= &d
->rel_hdr
;
2557 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2558 rel_hdr2
= d
->rel_hdr2
;
2559 reloc_count2
= (rel_hdr2
? NUM_SHDR_ENTRIES (rel_hdr2
) : 0);
2561 BFD_ASSERT (asect
->reloc_count
== reloc_count
+ reloc_count2
);
2562 BFD_ASSERT (asect
->rel_filepos
== rel_hdr
->sh_offset
2563 || (rel_hdr2
&& asect
->rel_filepos
== rel_hdr2
->sh_offset
));
2568 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2569 case because relocations against this section may use the
2570 dynamic symbol table, and in that case bfd_section_from_shdr
2571 in elf.c does not update the RELOC_COUNT. */
2572 if (asect
->size
== 0)
2575 rel_hdr
= &d
->this_hdr
;
2576 reloc_count
= NUM_SHDR_ENTRIES (rel_hdr
);
2581 /* Allocate space for 3 arelent structures for each Rel structure. */
2582 amt
= (reloc_count
+ reloc_count2
) * 3 * sizeof (arelent
);
2583 relents
= bfd_alloc (abfd
, amt
);
2584 if (relents
== NULL
)
2587 /* The slurp_one_reloc_table routine increments reloc_count. */
2588 asect
->reloc_count
= 0;
2590 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2591 rel_hdr
, reloc_count
,
2595 if (d
->rel_hdr2
!= NULL
)
2597 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
,
2598 rel_hdr2
, reloc_count2
,
2599 relents
+ reloc_count
* 3,
2604 asect
->relocation
= relents
;
2608 /* Write out the relocations. */
2611 mips_elf64_write_relocs (bfd
*abfd
, asection
*sec
, void *data
)
2613 bfd_boolean
*failedp
= data
;
2615 Elf_Internal_Shdr
*rel_hdr
;
2618 /* If we have already failed, don't do anything. */
2622 if ((sec
->flags
& SEC_RELOC
) == 0)
2625 /* The linker backend writes the relocs out itself, and sets the
2626 reloc_count field to zero to inhibit writing them here. Also,
2627 sometimes the SEC_RELOC flag gets set even when there aren't any
2629 if (sec
->reloc_count
== 0)
2632 /* We can combine up to three relocs that refer to the same address
2633 if the latter relocs have no associated symbol. */
2635 for (idx
= 0; idx
< sec
->reloc_count
; idx
++)
2642 addr
= sec
->orelocation
[idx
]->address
;
2643 for (i
= 0; i
< 2; i
++)
2647 if (idx
+ 1 >= sec
->reloc_count
)
2649 r
= sec
->orelocation
[idx
+ 1];
2650 if (r
->address
!= addr
2651 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2652 || (*r
->sym_ptr_ptr
)->value
!= 0)
2655 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2661 rel_hdr
= &elf_section_data (sec
)->rel_hdr
;
2663 /* Do the actual relocation. */
2665 if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rel
))
2666 mips_elf64_write_rel (abfd
, sec
, rel_hdr
, &count
, data
);
2667 else if (rel_hdr
->sh_entsize
== sizeof(Elf64_Mips_External_Rela
))
2668 mips_elf64_write_rela (abfd
, sec
, rel_hdr
, &count
, data
);
2674 mips_elf64_write_rel (bfd
*abfd
, asection
*sec
,
2675 Elf_Internal_Shdr
*rel_hdr
,
2676 int *count
, void *data
)
2678 bfd_boolean
*failedp
= data
;
2679 Elf64_Mips_External_Rel
*ext_rel
;
2681 asymbol
*last_sym
= 0;
2682 int last_sym_idx
= 0;
2684 rel_hdr
->sh_size
= rel_hdr
->sh_entsize
* *count
;
2685 rel_hdr
->contents
= bfd_alloc (abfd
, rel_hdr
->sh_size
);
2686 if (rel_hdr
->contents
== NULL
)
2692 ext_rel
= (Elf64_Mips_External_Rel
*) rel_hdr
->contents
;
2693 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rel
++)
2696 Elf64_Mips_Internal_Rela int_rel
;
2701 ptr
= sec
->orelocation
[idx
];
2703 /* The address of an ELF reloc is section relative for an object
2704 file, and absolute for an executable file or shared library.
2705 The address of a BFD reloc is always section relative. */
2706 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2707 int_rel
.r_offset
= ptr
->address
;
2709 int_rel
.r_offset
= ptr
->address
+ sec
->vma
;
2711 sym
= *ptr
->sym_ptr_ptr
;
2712 if (sym
== last_sym
)
2714 else if (bfd_is_abs_section (sym
->section
) && sym
->value
== 0)
2719 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2729 int_rel
.r_ssym
= RSS_UNDEF
;
2731 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2732 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2738 int_rel
.r_type
= ptr
->howto
->type
;
2739 int_rel
.r_type2
= (int) R_MIPS_NONE
;
2740 int_rel
.r_type3
= (int) R_MIPS_NONE
;
2742 for (i
= 0; i
< 2; i
++)
2746 if (idx
+ 1 >= sec
->reloc_count
)
2748 r
= sec
->orelocation
[idx
+ 1];
2749 if (r
->address
!= ptr
->address
2750 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2751 || (*r
->sym_ptr_ptr
)->value
!= 0)
2754 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2757 int_rel
.r_type2
= r
->howto
->type
;
2759 int_rel
.r_type3
= r
->howto
->type
;
2764 mips_elf64_swap_reloc_out (abfd
, &int_rel
, ext_rel
);
2767 BFD_ASSERT (ext_rel
- (Elf64_Mips_External_Rel
*) rel_hdr
->contents
2772 mips_elf64_write_rela (bfd
*abfd
, asection
*sec
,
2773 Elf_Internal_Shdr
*rela_hdr
,
2774 int *count
, void *data
)
2776 bfd_boolean
*failedp
= data
;
2777 Elf64_Mips_External_Rela
*ext_rela
;
2779 asymbol
*last_sym
= 0;
2780 int last_sym_idx
= 0;
2782 rela_hdr
->sh_size
= rela_hdr
->sh_entsize
* *count
;
2783 rela_hdr
->contents
= bfd_alloc (abfd
, rela_hdr
->sh_size
);
2784 if (rela_hdr
->contents
== NULL
)
2790 ext_rela
= (Elf64_Mips_External_Rela
*) rela_hdr
->contents
;
2791 for (idx
= 0; idx
< sec
->reloc_count
; idx
++, ext_rela
++)
2794 Elf64_Mips_Internal_Rela int_rela
;
2799 ptr
= sec
->orelocation
[idx
];
2801 /* The address of an ELF reloc is section relative for an object
2802 file, and absolute for an executable file or shared library.
2803 The address of a BFD reloc is always section relative. */
2804 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
2805 int_rela
.r_offset
= ptr
->address
;
2807 int_rela
.r_offset
= ptr
->address
+ sec
->vma
;
2809 sym
= *ptr
->sym_ptr_ptr
;
2810 if (sym
== last_sym
)
2812 else if (bfd_is_abs_section (sym
->section
) && sym
->value
== 0)
2817 n
= _bfd_elf_symbol_from_bfd_symbol (abfd
, &sym
);
2827 int_rela
.r_addend
= ptr
->addend
;
2828 int_rela
.r_ssym
= RSS_UNDEF
;
2830 if ((*ptr
->sym_ptr_ptr
)->the_bfd
->xvec
!= abfd
->xvec
2831 && ! _bfd_elf_validate_reloc (abfd
, ptr
))
2837 int_rela
.r_type
= ptr
->howto
->type
;
2838 int_rela
.r_type2
= (int) R_MIPS_NONE
;
2839 int_rela
.r_type3
= (int) R_MIPS_NONE
;
2841 for (i
= 0; i
< 2; i
++)
2845 if (idx
+ 1 >= sec
->reloc_count
)
2847 r
= sec
->orelocation
[idx
+ 1];
2848 if (r
->address
!= ptr
->address
2849 || ! bfd_is_abs_section ((*r
->sym_ptr_ptr
)->section
)
2850 || (*r
->sym_ptr_ptr
)->value
!= 0)
2853 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2856 int_rela
.r_type2
= r
->howto
->type
;
2858 int_rela
.r_type3
= r
->howto
->type
;
2863 mips_elf64_swap_reloca_out (abfd
, &int_rela
, ext_rela
);
2866 BFD_ASSERT (ext_rela
- (Elf64_Mips_External_Rela
*) rela_hdr
->contents
2870 /* Set the right machine number for a MIPS ELF file. */
2873 mips_elf64_object_p (bfd
*abfd
)
2877 /* Irix 6 is broken. Object file symbol tables are not always
2878 sorted correctly such that local symbols precede global symbols,
2879 and the sh_info field in the symbol table is not always right. */
2880 if (elf64_mips_irix_compat (abfd
) != ict_none
)
2881 elf_bad_symtab (abfd
) = TRUE
;
2883 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
2884 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
2888 /* Depending on the target vector we generate some version of Irix
2889 executables or "normal" MIPS ELF ABI executables. */
2890 static irix_compat_t
2891 elf64_mips_irix_compat (bfd
*abfd
)
2893 if ((abfd
->xvec
== &bfd_elf64_bigmips_vec
)
2894 || (abfd
->xvec
== &bfd_elf64_littlemips_vec
))
2900 /* Support for core dump NOTE sections. */
2902 elf64_mips_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
2907 switch (note
->descsz
)
2912 case 480: /* Linux/MIPS - N64 kernel */
2914 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
2917 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 32);
2926 /* Make a ".reg/999" section. */
2927 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
2928 size
, note
->descpos
+ offset
);
2932 elf64_mips_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
2934 switch (note
->descsz
)
2939 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2940 elf_tdata (abfd
)->core_program
2941 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
2942 elf_tdata (abfd
)->core_command
2943 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
2946 /* Note that for some reason, a spurious space is tacked
2947 onto the end of the args in some (at least one anyway)
2948 implementations, so strip it off if it exists. */
2951 char *command
= elf_tdata (abfd
)->core_command
;
2952 int n
= strlen (command
);
2954 if (0 < n
&& command
[n
- 1] == ' ')
2955 command
[n
- 1] = '\0';
2961 /* ECOFF swapping routines. These are used when dealing with the
2962 .mdebug section, which is in the ECOFF debugging format. */
2963 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap
=
2965 /* Symbol table magic number. */
2967 /* Alignment of debugging information. E.g., 4. */
2969 /* Sizes of external symbolic information. */
2970 sizeof (struct hdr_ext
),
2971 sizeof (struct dnr_ext
),
2972 sizeof (struct pdr_ext
),
2973 sizeof (struct sym_ext
),
2974 sizeof (struct opt_ext
),
2975 sizeof (struct fdr_ext
),
2976 sizeof (struct rfd_ext
),
2977 sizeof (struct ext_ext
),
2978 /* Functions to swap in external symbolic data. */
2987 _bfd_ecoff_swap_tir_in
,
2988 _bfd_ecoff_swap_rndx_in
,
2989 /* Functions to swap out external symbolic data. */
2998 _bfd_ecoff_swap_tir_out
,
2999 _bfd_ecoff_swap_rndx_out
,
3000 /* Function to read in symbolic data. */
3001 _bfd_mips_elf_read_ecoff_info
3004 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3005 standard ELF. This structure is used to redirect the relocation
3006 handling routines. */
3008 const struct elf_size_info mips_elf64_size_info
=
3010 sizeof (Elf64_External_Ehdr
),
3011 sizeof (Elf64_External_Phdr
),
3012 sizeof (Elf64_External_Shdr
),
3013 sizeof (Elf64_Mips_External_Rel
),
3014 sizeof (Elf64_Mips_External_Rela
),
3015 sizeof (Elf64_External_Sym
),
3016 sizeof (Elf64_External_Dyn
),
3017 sizeof (Elf_External_Note
),
3018 4, /* hash-table entry size */
3019 3, /* internal relocations per external relocations */
3021 3, /* log_file_align */
3024 bfd_elf64_write_out_phdrs
,
3025 bfd_elf64_write_shdrs_and_ehdr
,
3026 mips_elf64_write_relocs
,
3027 bfd_elf64_swap_symbol_in
,
3028 bfd_elf64_swap_symbol_out
,
3029 mips_elf64_slurp_reloc_table
,
3030 bfd_elf64_slurp_symbol_table
,
3031 bfd_elf64_swap_dyn_in
,
3032 bfd_elf64_swap_dyn_out
,
3033 mips_elf64_be_swap_reloc_in
,
3034 mips_elf64_be_swap_reloc_out
,
3035 mips_elf64_be_swap_reloca_in
,
3036 mips_elf64_be_swap_reloca_out
3039 #define ELF_ARCH bfd_arch_mips
3040 #define ELF_MACHINE_CODE EM_MIPS
3042 #define elf_backend_collect TRUE
3043 #define elf_backend_type_change_ok TRUE
3044 #define elf_backend_can_gc_sections TRUE
3045 #define elf_info_to_howto mips_elf64_info_to_howto_rela
3046 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
3047 #define elf_backend_object_p mips_elf64_object_p
3048 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3049 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3050 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3051 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3052 #define elf_backend_section_from_bfd_section \
3053 _bfd_mips_elf_section_from_bfd_section
3054 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3055 #define elf_backend_link_output_symbol_hook \
3056 _bfd_mips_elf_link_output_symbol_hook
3057 #define elf_backend_create_dynamic_sections \
3058 _bfd_mips_elf_create_dynamic_sections
3059 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3060 #define elf_backend_adjust_dynamic_symbol \
3061 _bfd_mips_elf_adjust_dynamic_symbol
3062 #define elf_backend_always_size_sections \
3063 _bfd_mips_elf_always_size_sections
3064 #define elf_backend_size_dynamic_sections \
3065 _bfd_mips_elf_size_dynamic_sections
3066 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3067 #define elf_backend_finish_dynamic_symbol \
3068 _bfd_mips_elf_finish_dynamic_symbol
3069 #define elf_backend_finish_dynamic_sections \
3070 _bfd_mips_elf_finish_dynamic_sections
3071 #define elf_backend_final_write_processing \
3072 _bfd_mips_elf_final_write_processing
3073 #define elf_backend_additional_program_headers \
3074 _bfd_mips_elf_additional_program_headers
3075 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3076 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3077 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3078 #define elf_backend_copy_indirect_symbol \
3079 _bfd_mips_elf_copy_indirect_symbol
3080 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
3081 #define elf_backend_ignore_discarded_relocs \
3082 _bfd_mips_elf_ignore_discarded_relocs
3083 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
3084 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3085 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3086 #define elf_backend_size_info mips_elf64_size_info
3088 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3089 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
3091 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3093 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3094 work better/work only in RELA, so we default to this. */
3095 #define elf_backend_may_use_rel_p 1
3096 #define elf_backend_may_use_rela_p 1
3097 #define elf_backend_default_use_rela_p 1
3099 #define elf_backend_write_section _bfd_mips_elf_write_section
3101 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3102 MIPS-specific function only applies to IRIX5, which had no 64-bit
3104 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
3105 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
3106 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
3107 #define bfd_elf64_bfd_get_relocated_section_contents \
3108 _bfd_elf_mips_get_relocated_section_contents
3109 #define bfd_elf64_bfd_link_hash_table_create \
3110 _bfd_mips_elf_link_hash_table_create
3111 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
3112 #define bfd_elf64_bfd_merge_private_bfd_data \
3113 _bfd_mips_elf_merge_private_bfd_data
3114 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3115 #define bfd_elf64_bfd_print_private_bfd_data \
3116 _bfd_mips_elf_print_private_bfd_data
3118 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3119 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3120 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3121 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3122 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
3124 /* MIPS ELF64 archive functions. */
3125 #define bfd_elf64_archive_functions
3126 extern bfd_boolean bfd_elf64_archive_slurp_armap
3128 extern bfd_boolean bfd_elf64_archive_write_armap
3129 (bfd
*, unsigned int, struct orl
*, unsigned int, int);
3130 #define bfd_elf64_archive_slurp_extended_name_table \
3131 _bfd_archive_coff_slurp_extended_name_table
3132 #define bfd_elf64_archive_construct_extended_name_table \
3133 _bfd_archive_coff_construct_extended_name_table
3134 #define bfd_elf64_archive_truncate_arname \
3135 _bfd_archive_coff_truncate_arname
3136 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3137 #define bfd_elf64_archive_openr_next_archived_file \
3138 _bfd_archive_coff_openr_next_archived_file
3139 #define bfd_elf64_archive_get_elt_at_index \
3140 _bfd_archive_coff_get_elt_at_index
3141 #define bfd_elf64_archive_generic_stat_arch_elt \
3142 _bfd_archive_coff_generic_stat_arch_elt
3143 #define bfd_elf64_archive_update_armap_timestamp \
3144 _bfd_archive_coff_update_armap_timestamp
3146 /* The SGI style (n)64 NewABI. */
3147 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3148 #define TARGET_LITTLE_NAME "elf64-littlemips"
3149 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3150 #define TARGET_BIG_NAME "elf64-bigmips"
3152 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
3153 a value of 0x1000, and we are compatible.
3154 FIXME: How does this affect NewABI? */
3155 #define ELF_MAXPAGESIZE 0x1000
3157 #include "elf64-target.h"
3159 /* The SYSV-style 'traditional' (n)64 NewABI. */
3160 #undef TARGET_LITTLE_SYM
3161 #undef TARGET_LITTLE_NAME
3162 #undef TARGET_BIG_SYM
3163 #undef TARGET_BIG_NAME
3165 #undef ELF_MAXPAGESIZE
3167 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3168 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3169 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3170 #define TARGET_BIG_NAME "elf64-tradbigmips"
3172 /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
3173 page sizes of up to that limit, so we need to respect it. */
3174 #define ELF_MAXPAGESIZE 0x10000
3175 #define elf64_bed elf64_tradbed
3177 /* Include the target file again for this target. */
3178 #include "elf64-target.h"