1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996 Free Software Foundation, Inc.
3 Ian Lance Taylor, Cygnus Support
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 /* This file supports the 64-bit MIPS ELF ABI.
31 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
32 overrides the usual ELF reloc handling, and handles reading and
33 writing the relocations here. */
35 static void mips_elf64_swap_reloc_in
36 PARAMS ((bfd
*, const Elf64_Mips_External_Rel
*,
37 Elf64_Mips_Internal_Rel
*));
38 static void mips_elf64_swap_reloca_in
39 PARAMS ((bfd
*, const Elf64_Mips_External_Rela
*,
40 Elf64_Mips_Internal_Rela
*));
41 static void mips_elf64_swap_reloc_out
42 PARAMS ((bfd
*, const Elf64_Mips_Internal_Rel
*,
43 Elf64_Mips_External_Rel
*));
44 static void mips_elf64_swap_reloca_out
45 PARAMS ((bfd
*, const Elf64_Mips_Internal_Rela
*,
46 Elf64_Mips_External_Rela
*));
47 static reloc_howto_type
*mips_elf64_reloc_type_lookup
48 PARAMS ((bfd
*, bfd_reloc_code_real_type
));
49 static boolean mips_elf64_slurp_one_reloc_table
50 PARAMS ((bfd
*, asection
*, asymbol
**, const Elf_Internal_Shdr
*));
51 static boolean mips_elf64_slurp_reloc_table
52 PARAMS ((bfd
*, asection
*, asymbol
**));
53 static void mips_elf64_write_relocs
PARAMS ((bfd
*, asection
*, PTR
));
54 static boolean mips_elf64_section_from_shdr
55 PARAMS ((bfd
*, Elf_Internal_Shdr
*, char *));
57 /* The relocation types. */
59 enum mips_elf64_reloc_type
93 R_MIPS_CALL_HI16
= 30,
94 R_MIPS_CALL_LO16
= 31,
97 R_MIPS_ADD_IMMEDIATE
= 34
100 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
101 from smaller values. Start with zero, widen, *then* decrement. */
102 #define MINUS_ONE (((bfd_vma)0) - 1)
104 /* FIXME: These need to be rewritten, or we need to use the versions
106 #define mips_elf_hi16_reloc bfd_elf_generic_reloc
107 #define mips_elf_lo16_reloc bfd_elf_generic_reloc
108 #define mips_elf_gprel16_reloc bfd_elf_generic_reloc
109 #define mips_elf_got16_reloc bfd_elf_generic_reloc
110 #define mips_elf_gprel32_reloc bfd_elf_generic_reloc
112 /* The relocation table used for SHT_REL sections. */
114 static reloc_howto_type mips_elf64_howto_table_rel
[] =
117 HOWTO (R_MIPS_NONE
, /* type */
119 0, /* size (0 = byte, 1 = short, 2 = long) */
121 false, /* pc_relative */
123 complain_overflow_dont
, /* complain_on_overflow */
124 bfd_elf_generic_reloc
, /* special_function */
125 "R_MIPS_NONE", /* name */
126 false, /* partial_inplace */
129 false), /* pcrel_offset */
131 /* 16 bit relocation. */
132 HOWTO (R_MIPS_16
, /* type */
134 1, /* size (0 = byte, 1 = short, 2 = long) */
136 false, /* pc_relative */
138 complain_overflow_bitfield
, /* complain_on_overflow */
139 bfd_elf_generic_reloc
, /* special_function */
140 "R_MIPS_16", /* name */
141 true, /* partial_inplace */
142 0xffff, /* src_mask */
143 0xffff, /* dst_mask */
144 false), /* pcrel_offset */
146 /* 32 bit relocation. */
147 HOWTO (R_MIPS_32
, /* type */
149 2, /* size (0 = byte, 1 = short, 2 = long) */
151 false, /* pc_relative */
153 complain_overflow_bitfield
, /* complain_on_overflow */
154 bfd_elf_generic_reloc
, /* special_function */
155 "R_MIPS_32", /* name */
156 true, /* partial_inplace */
157 0xffffffff, /* src_mask */
158 0xffffffff, /* dst_mask */
159 false), /* pcrel_offset */
161 /* 32 bit symbol relative relocation. */
162 HOWTO (R_MIPS_REL32
, /* type */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
166 false, /* pc_relative */
168 complain_overflow_bitfield
, /* complain_on_overflow */
169 bfd_elf_generic_reloc
, /* special_function */
170 "R_MIPS_REL32", /* name */
171 true, /* partial_inplace */
172 0xffffffff, /* src_mask */
173 0xffffffff, /* dst_mask */
174 false), /* pcrel_offset */
176 /* 26 bit branch address. */
177 HOWTO (R_MIPS_26
, /* type */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
181 false, /* pc_relative */
183 complain_overflow_dont
, /* complain_on_overflow */
184 /* This needs complex overflow
185 detection, because the upper four
186 bits must match the PC. */
187 bfd_elf_generic_reloc
, /* special_function */
188 "R_MIPS_26", /* name */
189 true, /* partial_inplace */
190 0x3ffffff, /* src_mask */
191 0x3ffffff, /* dst_mask */
192 false), /* pcrel_offset */
194 /* High 16 bits of symbol value. */
195 HOWTO (R_MIPS_HI16
, /* type */
197 2, /* size (0 = byte, 1 = short, 2 = long) */
199 false, /* pc_relative */
201 complain_overflow_dont
, /* complain_on_overflow */
202 mips_elf_hi16_reloc
, /* special_function */
203 "R_MIPS_HI16", /* name */
204 true, /* partial_inplace */
205 0xffff, /* src_mask */
206 0xffff, /* dst_mask */
207 false), /* pcrel_offset */
209 /* Low 16 bits of symbol value. */
210 HOWTO (R_MIPS_LO16
, /* type */
212 2, /* size (0 = byte, 1 = short, 2 = long) */
214 false, /* pc_relative */
216 complain_overflow_dont
, /* complain_on_overflow */
217 mips_elf_lo16_reloc
, /* special_function */
218 "R_MIPS_LO16", /* name */
219 true, /* partial_inplace */
220 0xffff, /* src_mask */
221 0xffff, /* dst_mask */
222 false), /* pcrel_offset */
224 /* GP relative reference. */
225 HOWTO (R_MIPS_GPREL16
, /* type */
227 2, /* size (0 = byte, 1 = short, 2 = long) */
229 false, /* pc_relative */
231 complain_overflow_signed
, /* complain_on_overflow */
232 mips_elf_gprel16_reloc
, /* special_function */
233 "R_MIPS_GPREL16", /* name */
234 true, /* partial_inplace */
235 0xffff, /* src_mask */
236 0xffff, /* dst_mask */
237 false), /* pcrel_offset */
239 /* Reference to literal section. */
240 HOWTO (R_MIPS_LITERAL
, /* type */
242 2, /* size (0 = byte, 1 = short, 2 = long) */
244 false, /* pc_relative */
246 complain_overflow_signed
, /* complain_on_overflow */
247 mips_elf_gprel16_reloc
, /* special_function */
248 "R_MIPS_LITERAL", /* name */
249 true, /* partial_inplace */
250 0xffff, /* src_mask */
251 0xffff, /* dst_mask */
252 false), /* pcrel_offset */
254 /* Reference to global offset table. */
255 HOWTO (R_MIPS_GOT16
, /* type */
257 2, /* size (0 = byte, 1 = short, 2 = long) */
259 false, /* pc_relative */
261 complain_overflow_signed
, /* complain_on_overflow */
262 mips_elf_got16_reloc
, /* special_function */
263 "R_MIPS_GOT16", /* name */
264 false, /* partial_inplace */
266 0xffff, /* dst_mask */
267 false), /* pcrel_offset */
269 /* 16 bit PC relative reference. */
270 HOWTO (R_MIPS_PC16
, /* type */
272 2, /* size (0 = byte, 1 = short, 2 = long) */
274 true, /* pc_relative */
276 complain_overflow_signed
, /* complain_on_overflow */
277 bfd_elf_generic_reloc
, /* special_function */
278 "R_MIPS_PC16", /* name */
279 true, /* partial_inplace */
280 0xffff, /* src_mask */
281 0xffff, /* dst_mask */
282 false), /* pcrel_offset */
284 /* 16 bit call through global offset table. */
285 /* FIXME: This is not handled correctly. */
286 HOWTO (R_MIPS_CALL16
, /* type */
288 2, /* size (0 = byte, 1 = short, 2 = long) */
290 false, /* pc_relative */
292 complain_overflow_signed
, /* complain_on_overflow */
293 bfd_elf_generic_reloc
, /* special_function */
294 "R_MIPS_CALL16", /* name */
295 false, /* partial_inplace */
297 0xffff, /* dst_mask */
298 false), /* pcrel_offset */
300 /* 32 bit GP relative reference. */
301 HOWTO (R_MIPS_GPREL32
, /* type */
303 2, /* size (0 = byte, 1 = short, 2 = long) */
305 false, /* pc_relative */
307 complain_overflow_bitfield
, /* complain_on_overflow */
308 mips_elf_gprel32_reloc
, /* special_function */
309 "R_MIPS_GPREL32", /* name */
310 true, /* partial_inplace */
311 0xffffffff, /* src_mask */
312 0xffffffff, /* dst_mask */
313 false), /* pcrel_offset */
319 /* A 5 bit shift field. */
320 HOWTO (R_MIPS_SHIFT5
, /* type */
322 2, /* size (0 = byte, 1 = short, 2 = long) */
324 false, /* pc_relative */
326 complain_overflow_bitfield
, /* complain_on_overflow */
327 bfd_elf_generic_reloc
, /* special_function */
328 "R_MIPS_SHIFT5", /* name */
329 true, /* partial_inplace */
330 0x000007c0, /* src_mask */
331 0x000007c0, /* dst_mask */
332 false), /* pcrel_offset */
334 /* A 6 bit shift field. */
335 /* FIXME: This is not handled correctly; a special function is
336 needed to put the most significant bit in the right place. */
337 HOWTO (R_MIPS_SHIFT6
, /* type */
339 2, /* size (0 = byte, 1 = short, 2 = long) */
341 false, /* pc_relative */
343 complain_overflow_bitfield
, /* complain_on_overflow */
344 bfd_elf_generic_reloc
, /* special_function */
345 "R_MIPS_SHIFT6", /* name */
346 true, /* partial_inplace */
347 0x000007c4, /* src_mask */
348 0x000007c4, /* dst_mask */
349 false), /* pcrel_offset */
351 /* 64 bit relocation. */
352 HOWTO (R_MIPS_64
, /* type */
354 4, /* size (0 = byte, 1 = short, 2 = long) */
356 false, /* pc_relative */
358 complain_overflow_bitfield
, /* complain_on_overflow */
359 bfd_elf_generic_reloc
, /* special_function */
360 "R_MIPS_64", /* name */
361 true, /* partial_inplace */
362 MINUS_ONE
, /* src_mask */
363 MINUS_ONE
, /* dst_mask */
364 false), /* pcrel_offset */
366 /* Displacement in the global offset table. */
367 /* FIXME: Not handled correctly. */
368 HOWTO (R_MIPS_GOT_DISP
, /* type */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
372 false, /* pc_relative */
374 complain_overflow_bitfield
, /* complain_on_overflow */
375 bfd_elf_generic_reloc
, /* special_function */
376 "R_MIPS_GOT_DISP", /* name */
377 true, /* partial_inplace */
378 0x0000ffff, /* src_mask */
379 0x0000ffff, /* dst_mask */
380 false), /* pcrel_offset */
382 /* Displacement to page pointer in the global offset table. */
383 /* FIXME: Not handled correctly. */
384 HOWTO (R_MIPS_GOT_PAGE
, /* type */
386 2, /* size (0 = byte, 1 = short, 2 = long) */
388 false, /* pc_relative */
390 complain_overflow_bitfield
, /* complain_on_overflow */
391 bfd_elf_generic_reloc
, /* special_function */
392 "R_MIPS_GOT_PAGE", /* name */
393 true, /* partial_inplace */
394 0x0000ffff, /* src_mask */
395 0x0000ffff, /* dst_mask */
396 false), /* pcrel_offset */
398 /* Offset from page pointer in the global offset table. */
399 /* FIXME: Not handled correctly. */
400 HOWTO (R_MIPS_GOT_OFST
, /* type */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
404 false, /* pc_relative */
406 complain_overflow_bitfield
, /* complain_on_overflow */
407 bfd_elf_generic_reloc
, /* special_function */
408 "R_MIPS_GOT_OFST", /* name */
409 true, /* partial_inplace */
410 0x0000ffff, /* src_mask */
411 0x0000ffff, /* dst_mask */
412 false), /* pcrel_offset */
414 /* High 16 bits of displacement in global offset table. */
415 /* FIXME: Not handled correctly. */
416 HOWTO (R_MIPS_GOT_HI16
, /* type */
418 2, /* size (0 = byte, 1 = short, 2 = long) */
420 false, /* pc_relative */
422 complain_overflow_dont
, /* complain_on_overflow */
423 bfd_elf_generic_reloc
, /* special_function */
424 "R_MIPS_GOT_HI16", /* name */
425 true, /* partial_inplace */
426 0x0000ffff, /* src_mask */
427 0x0000ffff, /* dst_mask */
428 false), /* pcrel_offset */
430 /* Low 16 bits of displacement in global offset table. */
431 /* FIXME: Not handled correctly. */
432 HOWTO (R_MIPS_GOT_LO16
, /* type */
434 2, /* size (0 = byte, 1 = short, 2 = long) */
436 false, /* pc_relative */
438 complain_overflow_dont
, /* complain_on_overflow */
439 bfd_elf_generic_reloc
, /* special_function */
440 "R_MIPS_GOT_LO16", /* name */
441 true, /* partial_inplace */
442 0x0000ffff, /* src_mask */
443 0x0000ffff, /* dst_mask */
444 false), /* pcrel_offset */
446 /* 64 bit substraction. */
447 /* FIXME: Not handled correctly. */
448 HOWTO (R_MIPS_SUB
, /* type */
450 4, /* size (0 = byte, 1 = short, 2 = long) */
452 false, /* pc_relative */
454 complain_overflow_bitfield
, /* complain_on_overflow */
455 bfd_elf_generic_reloc
, /* special_function */
456 "R_MIPS_SUB", /* name */
457 true, /* partial_inplace */
458 MINUS_ONE
, /* src_mask */
459 MINUS_ONE
, /* dst_mask */
460 false), /* pcrel_offset */
462 /* Insert the addend as an instruction. */
463 /* FIXME: Not handled correctly. */
464 HOWTO (R_MIPS_INSERT_A
, /* type */
466 0, /* size (0 = byte, 1 = short, 2 = long) */
468 false, /* pc_relative */
470 complain_overflow_dont
, /* complain_on_overflow */
471 bfd_elf_generic_reloc
, /* special_function */
472 "R_MIPS_INSERT_A", /* name */
473 false, /* partial_inplace */
476 false), /* pcrel_offset */
478 /* Insert the addend as an instruction, and change all relocations
479 to refer to the old instruction at the address. */
480 /* FIXME: Not handled correctly. */
481 HOWTO (R_MIPS_INSERT_B
, /* type */
483 0, /* size (0 = byte, 1 = short, 2 = long) */
485 false, /* pc_relative */
487 complain_overflow_dont
, /* complain_on_overflow */
488 bfd_elf_generic_reloc
, /* special_function */
489 "R_MIPS_INSERT_B", /* name */
490 false, /* partial_inplace */
493 false), /* pcrel_offset */
495 /* Delete a 32 bit instruction. */
496 /* FIXME: Not handled correctly. */
497 HOWTO (R_MIPS_DELETE
, /* type */
499 0, /* size (0 = byte, 1 = short, 2 = long) */
501 false, /* pc_relative */
503 complain_overflow_dont
, /* complain_on_overflow */
504 bfd_elf_generic_reloc
, /* special_function */
505 "R_MIPS_DELETE", /* name */
506 false, /* partial_inplace */
509 false), /* pcrel_offset */
511 /* Get the higher value of a 64 bit addend. */
512 /* FIXME: Not handled correctly. */
513 HOWTO (R_MIPS_HIGHER
, /* type */
515 2, /* size (0 = byte, 1 = short, 2 = long) */
517 false, /* pc_relative */
519 complain_overflow_dont
, /* complain_on_overflow */
520 bfd_elf_generic_reloc
, /* special_function */
521 "R_MIPS_HIGHER", /* name */
522 true, /* partial_inplace */
523 0xffff, /* src_mask */
524 0xffff, /* dst_mask */
525 false), /* pcrel_offset */
527 /* Get the highest value of a 64 bit addend. */
528 /* FIXME: Not handled correctly. */
529 HOWTO (R_MIPS_HIGHEST
, /* type */
531 2, /* size (0 = byte, 1 = short, 2 = long) */
533 false, /* pc_relative */
535 complain_overflow_dont
, /* complain_on_overflow */
536 bfd_elf_generic_reloc
, /* special_function */
537 "R_MIPS_HIGHEST", /* name */
538 true, /* partial_inplace */
539 0xffff, /* src_mask */
540 0xffff, /* dst_mask */
541 false), /* pcrel_offset */
543 /* High 16 bits of displacement in global offset table. */
544 /* FIXME: Not handled correctly. */
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_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 /* FIXME: Not handled correctly. */
561 HOWTO (R_MIPS_CALL_LO16
, /* type */
563 2, /* size (0 = byte, 1 = short, 2 = long) */
565 false, /* pc_relative */
567 complain_overflow_dont
, /* complain_on_overflow */
568 bfd_elf_generic_reloc
, /* special_function */
569 "R_MIPS_CALL_LO16", /* name */
570 true, /* partial_inplace */
571 0x0000ffff, /* src_mask */
572 0x0000ffff, /* dst_mask */
573 false), /* pcrel_offset */
575 /* I'm not sure what the remaining relocs are, but they are defined
578 HOWTO (R_MIPS_SCN_DISP
, /* type */
580 0, /* size (0 = byte, 1 = short, 2 = long) */
582 false, /* pc_relative */
584 complain_overflow_dont
, /* complain_on_overflow */
585 bfd_elf_generic_reloc
, /* special_function */
586 "R_MIPS_SCN_DISP", /* name */
587 false, /* partial_inplace */
590 false), /* pcrel_offset */
592 HOWTO (R_MIPS_REL16
, /* type */
594 0, /* size (0 = byte, 1 = short, 2 = long) */
596 false, /* pc_relative */
598 complain_overflow_dont
, /* complain_on_overflow */
599 bfd_elf_generic_reloc
, /* special_function */
600 "R_MIPS_REL16", /* name */
601 false, /* partial_inplace */
604 false), /* pcrel_offset */
606 HOWTO (R_MIPS_ADD_IMMEDIATE
, /* type */
608 0, /* size (0 = byte, 1 = short, 2 = long) */
610 false, /* pc_relative */
612 complain_overflow_dont
, /* complain_on_overflow */
613 bfd_elf_generic_reloc
, /* special_function */
614 "R_MIPS_ADD_IMMEDIATE", /* name */
615 false, /* partial_inplace */
618 false) /* pcrel_offset */
621 /* The relocation table used for SHT_RELA sections. */
623 static reloc_howto_type mips_elf64_howto_table_rela
[] =
626 HOWTO (R_MIPS_NONE
, /* type */
628 0, /* size (0 = byte, 1 = short, 2 = long) */
630 false, /* pc_relative */
632 complain_overflow_dont
, /* complain_on_overflow */
633 bfd_elf_generic_reloc
, /* special_function */
634 "R_MIPS_NONE", /* name */
635 false, /* partial_inplace */
638 false), /* pcrel_offset */
640 /* 16 bit relocation. */
641 HOWTO (R_MIPS_16
, /* type */
643 1, /* size (0 = byte, 1 = short, 2 = long) */
645 false, /* pc_relative */
647 complain_overflow_bitfield
, /* complain_on_overflow */
648 bfd_elf_generic_reloc
, /* special_function */
649 "R_MIPS_16", /* name */
650 true, /* partial_inplace */
652 0xffff, /* dst_mask */
653 false), /* pcrel_offset */
655 /* 32 bit relocation. */
656 HOWTO (R_MIPS_32
, /* type */
658 2, /* size (0 = byte, 1 = short, 2 = long) */
660 false, /* pc_relative */
662 complain_overflow_bitfield
, /* complain_on_overflow */
663 bfd_elf_generic_reloc
, /* special_function */
664 "R_MIPS_32", /* name */
665 true, /* partial_inplace */
667 0xffffffff, /* dst_mask */
668 false), /* pcrel_offset */
670 /* 32 bit symbol relative relocation. */
671 HOWTO (R_MIPS_REL32
, /* type */
673 2, /* size (0 = byte, 1 = short, 2 = long) */
675 false, /* pc_relative */
677 complain_overflow_bitfield
, /* complain_on_overflow */
678 bfd_elf_generic_reloc
, /* special_function */
679 "R_MIPS_REL32", /* name */
680 true, /* partial_inplace */
682 0xffffffff, /* dst_mask */
683 false), /* pcrel_offset */
685 /* 26 bit branch address. */
686 HOWTO (R_MIPS_26
, /* type */
688 2, /* size (0 = byte, 1 = short, 2 = long) */
690 false, /* pc_relative */
692 complain_overflow_dont
, /* complain_on_overflow */
693 /* This needs complex overflow
694 detection, because the upper four
695 bits must match the PC. */
696 bfd_elf_generic_reloc
, /* special_function */
697 "R_MIPS_26", /* name */
698 true, /* partial_inplace */
700 0x3ffffff, /* dst_mask */
701 false), /* pcrel_offset */
703 /* High 16 bits of symbol value. */
704 HOWTO (R_MIPS_HI16
, /* type */
706 2, /* size (0 = byte, 1 = short, 2 = long) */
708 false, /* pc_relative */
710 complain_overflow_dont
, /* complain_on_overflow */
711 bfd_elf_generic_reloc
, /* special_function */
712 "R_MIPS_HI16", /* name */
713 true, /* partial_inplace */
715 0xffff, /* dst_mask */
716 false), /* pcrel_offset */
718 /* Low 16 bits of symbol value. */
719 HOWTO (R_MIPS_LO16
, /* type */
721 2, /* size (0 = byte, 1 = short, 2 = long) */
723 false, /* pc_relative */
725 complain_overflow_dont
, /* complain_on_overflow */
726 bfd_elf_generic_reloc
, /* special_function */
727 "R_MIPS_LO16", /* name */
728 true, /* partial_inplace */
730 0xffff, /* dst_mask */
731 false), /* pcrel_offset */
733 /* GP relative reference. */
734 HOWTO (R_MIPS_GPREL16
, /* type */
736 2, /* size (0 = byte, 1 = short, 2 = long) */
738 false, /* pc_relative */
740 complain_overflow_signed
, /* complain_on_overflow */
741 mips_elf_gprel16_reloc
, /* special_function */
742 "R_MIPS_GPREL16", /* name */
743 true, /* partial_inplace */
745 0xffff, /* dst_mask */
746 false), /* pcrel_offset */
748 /* Reference to literal section. */
749 HOWTO (R_MIPS_LITERAL
, /* type */
751 2, /* size (0 = byte, 1 = short, 2 = long) */
753 false, /* pc_relative */
755 complain_overflow_signed
, /* complain_on_overflow */
756 mips_elf_gprel16_reloc
, /* special_function */
757 "R_MIPS_LITERAL", /* name */
758 true, /* partial_inplace */
760 0xffff, /* dst_mask */
761 false), /* pcrel_offset */
763 /* Reference to global offset table. */
764 HOWTO (R_MIPS_GOT16
, /* type */
766 2, /* size (0 = byte, 1 = short, 2 = long) */
768 false, /* pc_relative */
770 complain_overflow_signed
, /* complain_on_overflow */
771 mips_elf_got16_reloc
, /* special_function */
772 "R_MIPS_GOT16", /* name */
773 false, /* partial_inplace */
775 0xffff, /* dst_mask */
776 false), /* pcrel_offset */
778 /* 16 bit PC relative reference. */
779 HOWTO (R_MIPS_PC16
, /* type */
781 2, /* size (0 = byte, 1 = short, 2 = long) */
783 true, /* pc_relative */
785 complain_overflow_signed
, /* complain_on_overflow */
786 bfd_elf_generic_reloc
, /* special_function */
787 "R_MIPS_PC16", /* name */
788 true, /* partial_inplace */
790 0xffff, /* dst_mask */
791 false), /* pcrel_offset */
793 /* 16 bit call through global offset table. */
794 /* FIXME: This is not handled correctly. */
795 HOWTO (R_MIPS_CALL16
, /* type */
797 2, /* size (0 = byte, 1 = short, 2 = long) */
799 false, /* pc_relative */
801 complain_overflow_signed
, /* complain_on_overflow */
802 bfd_elf_generic_reloc
, /* special_function */
803 "R_MIPS_CALL16", /* name */
804 false, /* partial_inplace */
806 0xffff, /* dst_mask */
807 false), /* pcrel_offset */
809 /* 32 bit GP relative reference. */
810 HOWTO (R_MIPS_GPREL32
, /* type */
812 2, /* size (0 = byte, 1 = short, 2 = long) */
814 false, /* pc_relative */
816 complain_overflow_bitfield
, /* complain_on_overflow */
817 mips_elf_gprel32_reloc
, /* special_function */
818 "R_MIPS_GPREL32", /* name */
819 true, /* partial_inplace */
821 0xffffffff, /* dst_mask */
822 false), /* pcrel_offset */
828 /* A 5 bit shift field. */
829 HOWTO (R_MIPS_SHIFT5
, /* type */
831 2, /* size (0 = byte, 1 = short, 2 = long) */
833 false, /* pc_relative */
835 complain_overflow_bitfield
, /* complain_on_overflow */
836 bfd_elf_generic_reloc
, /* special_function */
837 "R_MIPS_SHIFT5", /* name */
838 true, /* partial_inplace */
840 0x000007c0, /* dst_mask */
841 false), /* pcrel_offset */
843 /* A 6 bit shift field. */
844 /* FIXME: This is not handled correctly; a special function is
845 needed to put the most significant bit in the right place. */
846 HOWTO (R_MIPS_SHIFT6
, /* type */
848 2, /* size (0 = byte, 1 = short, 2 = long) */
850 false, /* pc_relative */
852 complain_overflow_bitfield
, /* complain_on_overflow */
853 bfd_elf_generic_reloc
, /* special_function */
854 "R_MIPS_SHIFT6", /* name */
855 true, /* partial_inplace */
857 0x000007c4, /* dst_mask */
858 false), /* pcrel_offset */
860 /* 64 bit relocation. */
861 HOWTO (R_MIPS_64
, /* type */
863 4, /* size (0 = byte, 1 = short, 2 = long) */
865 false, /* pc_relative */
867 complain_overflow_bitfield
, /* complain_on_overflow */
868 bfd_elf_generic_reloc
, /* special_function */
869 "R_MIPS_64", /* name */
870 true, /* partial_inplace */
872 MINUS_ONE
, /* dst_mask */
873 false), /* pcrel_offset */
875 /* Displacement in the global offset table. */
876 /* FIXME: Not handled correctly. */
877 HOWTO (R_MIPS_GOT_DISP
, /* type */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
881 false, /* pc_relative */
883 complain_overflow_bitfield
, /* complain_on_overflow */
884 bfd_elf_generic_reloc
, /* special_function */
885 "R_MIPS_GOT_DISP", /* name */
886 true, /* partial_inplace */
888 0x0000ffff, /* dst_mask */
889 false), /* pcrel_offset */
891 /* Displacement to page pointer in the global offset table. */
892 /* FIXME: Not handled correctly. */
893 HOWTO (R_MIPS_GOT_PAGE
, /* type */
895 2, /* size (0 = byte, 1 = short, 2 = long) */
897 false, /* pc_relative */
899 complain_overflow_bitfield
, /* complain_on_overflow */
900 bfd_elf_generic_reloc
, /* special_function */
901 "R_MIPS_GOT_PAGE", /* name */
902 true, /* partial_inplace */
904 0x0000ffff, /* dst_mask */
905 false), /* pcrel_offset */
907 /* Offset from page pointer in the global offset table. */
908 /* FIXME: Not handled correctly. */
909 HOWTO (R_MIPS_GOT_OFST
, /* type */
911 2, /* size (0 = byte, 1 = short, 2 = long) */
913 false, /* pc_relative */
915 complain_overflow_bitfield
, /* complain_on_overflow */
916 bfd_elf_generic_reloc
, /* special_function */
917 "R_MIPS_GOT_OFST", /* name */
918 true, /* partial_inplace */
920 0x0000ffff, /* dst_mask */
921 false), /* pcrel_offset */
923 /* High 16 bits of displacement in global offset table. */
924 /* FIXME: Not handled correctly. */
925 HOWTO (R_MIPS_GOT_HI16
, /* type */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
929 false, /* pc_relative */
931 complain_overflow_dont
, /* complain_on_overflow */
932 bfd_elf_generic_reloc
, /* special_function */
933 "R_MIPS_GOT_HI16", /* name */
934 true, /* partial_inplace */
936 0x0000ffff, /* dst_mask */
937 false), /* pcrel_offset */
939 /* Low 16 bits of displacement in global offset table. */
940 /* FIXME: Not handled correctly. */
941 HOWTO (R_MIPS_GOT_LO16
, /* type */
943 2, /* size (0 = byte, 1 = short, 2 = long) */
945 false, /* pc_relative */
947 complain_overflow_dont
, /* complain_on_overflow */
948 bfd_elf_generic_reloc
, /* special_function */
949 "R_MIPS_GOT_LO16", /* name */
950 true, /* partial_inplace */
952 0x0000ffff, /* dst_mask */
953 false), /* pcrel_offset */
955 /* 64 bit substraction. */
956 /* FIXME: Not handled correctly. */
957 HOWTO (R_MIPS_SUB
, /* type */
959 4, /* size (0 = byte, 1 = short, 2 = long) */
961 false, /* pc_relative */
963 complain_overflow_bitfield
, /* complain_on_overflow */
964 bfd_elf_generic_reloc
, /* special_function */
965 "R_MIPS_SUB", /* name */
966 true, /* partial_inplace */
968 MINUS_ONE
, /* dst_mask */
969 false), /* pcrel_offset */
971 /* Insert the addend as an instruction. */
972 /* FIXME: Not handled correctly. */
973 HOWTO (R_MIPS_INSERT_A
, /* type */
975 0, /* size (0 = byte, 1 = short, 2 = long) */
977 false, /* pc_relative */
979 complain_overflow_dont
, /* complain_on_overflow */
980 bfd_elf_generic_reloc
, /* special_function */
981 "R_MIPS_INSERT_A", /* name */
982 false, /* partial_inplace */
985 false), /* pcrel_offset */
987 /* Insert the addend as an instruction, and change all relocations
988 to refer to the old instruction at the address. */
989 /* FIXME: Not handled correctly. */
990 HOWTO (R_MIPS_INSERT_B
, /* type */
992 0, /* size (0 = byte, 1 = short, 2 = long) */
994 false, /* pc_relative */
996 complain_overflow_dont
, /* complain_on_overflow */
997 bfd_elf_generic_reloc
, /* special_function */
998 "R_MIPS_INSERT_B", /* name */
999 false, /* partial_inplace */
1002 false), /* pcrel_offset */
1004 /* Delete a 32 bit instruction. */
1005 /* FIXME: Not handled correctly. */
1006 HOWTO (R_MIPS_DELETE
, /* type */
1008 0, /* size (0 = byte, 1 = short, 2 = long) */
1010 false, /* pc_relative */
1012 complain_overflow_dont
, /* complain_on_overflow */
1013 bfd_elf_generic_reloc
, /* special_function */
1014 "R_MIPS_DELETE", /* name */
1015 false, /* partial_inplace */
1018 false), /* pcrel_offset */
1020 /* Get the higher value of a 64 bit addend. */
1021 /* FIXME: Not handled correctly. */
1022 HOWTO (R_MIPS_HIGHER
, /* type */
1024 2, /* size (0 = byte, 1 = short, 2 = long) */
1026 false, /* pc_relative */
1028 complain_overflow_dont
, /* complain_on_overflow */
1029 bfd_elf_generic_reloc
, /* special_function */
1030 "R_MIPS_HIGHER", /* name */
1031 true, /* partial_inplace */
1033 0xffff, /* dst_mask */
1034 false), /* pcrel_offset */
1036 /* Get the highest value of a 64 bit addend. */
1037 /* FIXME: Not handled correctly. */
1038 HOWTO (R_MIPS_HIGHEST
, /* type */
1040 2, /* size (0 = byte, 1 = short, 2 = long) */
1042 false, /* pc_relative */
1044 complain_overflow_dont
, /* complain_on_overflow */
1045 bfd_elf_generic_reloc
, /* special_function */
1046 "R_MIPS_HIGHEST", /* name */
1047 true, /* partial_inplace */
1049 0xffff, /* dst_mask */
1050 false), /* pcrel_offset */
1052 /* High 16 bits of displacement in global offset table. */
1053 /* FIXME: Not handled correctly. */
1054 HOWTO (R_MIPS_CALL_HI16
, /* type */
1056 2, /* size (0 = byte, 1 = short, 2 = long) */
1058 false, /* pc_relative */
1060 complain_overflow_dont
, /* complain_on_overflow */
1061 bfd_elf_generic_reloc
, /* special_function */
1062 "R_MIPS_CALL_HI16", /* name */
1063 true, /* partial_inplace */
1065 0x0000ffff, /* dst_mask */
1066 false), /* pcrel_offset */
1068 /* Low 16 bits of displacement in global offset table. */
1069 /* FIXME: Not handled correctly. */
1070 HOWTO (R_MIPS_CALL_LO16
, /* type */
1072 2, /* size (0 = byte, 1 = short, 2 = long) */
1074 false, /* pc_relative */
1076 complain_overflow_dont
, /* complain_on_overflow */
1077 bfd_elf_generic_reloc
, /* special_function */
1078 "R_MIPS_CALL_LO16", /* name */
1079 true, /* partial_inplace */
1081 0x0000ffff, /* dst_mask */
1082 false), /* pcrel_offset */
1084 /* I'm not sure what the remaining relocs are, but they are defined
1087 HOWTO (R_MIPS_SCN_DISP
, /* type */
1089 0, /* size (0 = byte, 1 = short, 2 = long) */
1091 false, /* pc_relative */
1093 complain_overflow_dont
, /* complain_on_overflow */
1094 bfd_elf_generic_reloc
, /* special_function */
1095 "R_MIPS_SCN_DISP", /* name */
1096 false, /* partial_inplace */
1099 false), /* pcrel_offset */
1101 HOWTO (R_MIPS_REL16
, /* type */
1103 0, /* size (0 = byte, 1 = short, 2 = long) */
1105 false, /* pc_relative */
1107 complain_overflow_dont
, /* complain_on_overflow */
1108 bfd_elf_generic_reloc
, /* special_function */
1109 "R_MIPS_REL16", /* name */
1110 false, /* partial_inplace */
1113 false), /* pcrel_offset */
1115 HOWTO (R_MIPS_ADD_IMMEDIATE
, /* type */
1117 0, /* size (0 = byte, 1 = short, 2 = long) */
1119 false, /* pc_relative */
1121 complain_overflow_dont
, /* complain_on_overflow */
1122 bfd_elf_generic_reloc
, /* special_function */
1123 "R_MIPS_ADD_IMMEDIATE", /* name */
1124 false, /* partial_inplace */
1127 false) /* pcrel_offset */
1130 /* Swap in a MIPS 64-bit Rel reloc. */
1133 mips_elf64_swap_reloc_in (abfd
, src
, dst
)
1135 const Elf64_Mips_External_Rel
*src
;
1136 Elf64_Mips_Internal_Rel
*dst
;
1138 dst
->r_offset
= bfd_h_get_64 (abfd
, (bfd_byte
*) src
->r_offset
);
1139 dst
->r_sym
= bfd_h_get_32 (abfd
, (bfd_byte
*) src
->r_sym
);
1140 dst
->r_ssym
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_ssym
);
1141 dst
->r_type3
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_type3
);
1142 dst
->r_type2
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_type2
);
1143 dst
->r_type
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_type
);
1146 /* Swap in a MIPS 64-bit Rela reloc. */
1149 mips_elf64_swap_reloca_in (abfd
, src
, dst
)
1151 const Elf64_Mips_External_Rela
*src
;
1152 Elf64_Mips_Internal_Rela
*dst
;
1154 dst
->r_offset
= bfd_h_get_64 (abfd
, (bfd_byte
*) src
->r_offset
);
1155 dst
->r_sym
= bfd_h_get_32 (abfd
, (bfd_byte
*) src
->r_sym
);
1156 dst
->r_ssym
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_ssym
);
1157 dst
->r_type3
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_type3
);
1158 dst
->r_type2
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_type2
);
1159 dst
->r_type
= bfd_h_get_8 (abfd
, (bfd_byte
*) src
->r_type
);
1160 dst
->r_addend
= bfd_h_get_64 (abfd
, (bfd_byte
*) src
->r_addend
);
1163 /* Swap out a MIPS 64-bit Rel reloc. */
1166 mips_elf64_swap_reloc_out (abfd
, src
, dst
)
1168 const Elf64_Mips_Internal_Rel
*src
;
1169 Elf64_Mips_External_Rel
*dst
;
1171 bfd_h_put_64 (abfd
, src
->r_offset
, (bfd_byte
*) dst
->r_offset
);
1172 bfd_h_put_32 (abfd
, src
->r_sym
, (bfd_byte
*) dst
->r_sym
);
1173 bfd_h_put_8 (abfd
, src
->r_ssym
, (bfd_byte
*) dst
->r_ssym
);
1174 bfd_h_put_8 (abfd
, src
->r_type3
, (bfd_byte
*) dst
->r_type3
);
1175 bfd_h_put_8 (abfd
, src
->r_type2
, (bfd_byte
*) dst
->r_type2
);
1176 bfd_h_put_8 (abfd
, src
->r_type
, (bfd_byte
*) dst
->r_type
);
1179 /* Swap out a MIPS 64-bit Rela reloc. */
1182 mips_elf64_swap_reloca_out (abfd
, src
, dst
)
1184 const Elf64_Mips_Internal_Rela
*src
;
1185 Elf64_Mips_External_Rela
*dst
;
1187 bfd_h_put_64 (abfd
, src
->r_offset
, (bfd_byte
*) dst
->r_offset
);
1188 bfd_h_put_32 (abfd
, src
->r_sym
, (bfd_byte
*) dst
->r_sym
);
1189 bfd_h_put_8 (abfd
, src
->r_ssym
, (bfd_byte
*) dst
->r_ssym
);
1190 bfd_h_put_8 (abfd
, src
->r_type3
, (bfd_byte
*) dst
->r_type3
);
1191 bfd_h_put_8 (abfd
, src
->r_type2
, (bfd_byte
*) dst
->r_type2
);
1192 bfd_h_put_8 (abfd
, src
->r_type
, (bfd_byte
*) dst
->r_type
);
1193 bfd_h_put_64 (abfd
, src
->r_offset
, (bfd_byte
*) dst
->r_offset
);
1196 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1198 struct elf_reloc_map
1200 bfd_reloc_code_real_type bfd_reloc_val
;
1201 enum mips_elf64_reloc_type elf_reloc_val
;
1204 static CONST
struct elf_reloc_map mips_reloc_map
[] =
1206 { BFD_RELOC_NONE
, R_MIPS_NONE
, },
1207 { BFD_RELOC_16
, R_MIPS_16
},
1208 { BFD_RELOC_32
, R_MIPS_32
},
1209 { BFD_RELOC_64
, R_MIPS_64
},
1210 { BFD_RELOC_CTOR
, R_MIPS_64
},
1211 { BFD_RELOC_32_PCREL
, R_MIPS_REL32
},
1212 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
1213 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
1214 { BFD_RELOC_LO16
, R_MIPS_LO16
},
1215 { BFD_RELOC_MIPS_GPREL
, R_MIPS_GPREL16
},
1216 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
1217 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
1218 { BFD_RELOC_16_PCREL
, R_MIPS_PC16
},
1219 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
1220 { BFD_RELOC_MIPS_GPREL32
, R_MIPS_GPREL32
},
1221 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
1222 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
1223 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
1224 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
}
1227 /* Given a BFD reloc type, return a howto structure. */
1229 static reloc_howto_type
*
1230 mips_elf64_reloc_type_lookup (abfd
, code
)
1232 bfd_reloc_code_real_type code
;
1236 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
); i
++)
1238 if (mips_reloc_map
[i
].bfd_reloc_val
== code
)
1242 v
= (int) mips_reloc_map
[i
].elf_reloc_val
;
1243 return &mips_elf64_howto_table_rel
[v
];
1250 /* Read the relocations from one reloc section. */
1253 mips_elf64_slurp_one_reloc_table (abfd
, asect
, symbols
, rel_hdr
)
1257 const Elf_Internal_Shdr
*rel_hdr
;
1259 PTR allocated
= NULL
;
1260 bfd_byte
*native_relocs
;
1266 reloc_howto_type
*howto_table
;
1268 allocated
= (PTR
) bfd_malloc (rel_hdr
->sh_size
);
1269 if (allocated
== NULL
)
1272 if (bfd_seek (abfd
, rel_hdr
->sh_offset
, SEEK_SET
) != 0
1273 || (bfd_read (allocated
, 1, rel_hdr
->sh_size
, abfd
) != rel_hdr
->sh_size
))
1276 native_relocs
= (bfd_byte
*) allocated
;
1278 relents
= asect
->relocation
+ asect
->reloc_count
;
1280 entsize
= rel_hdr
->sh_entsize
;
1281 BFD_ASSERT (entsize
== sizeof (Elf64_Mips_External_Rel
)
1282 || entsize
== sizeof (Elf64_Mips_External_Rela
));
1284 count
= rel_hdr
->sh_size
/ entsize
;
1286 if (entsize
== sizeof (Elf64_Mips_External_Rel
))
1287 howto_table
= mips_elf64_howto_table_rel
;
1289 howto_table
= mips_elf64_howto_table_rela
;
1292 for (i
= 0; i
< count
; i
++, native_relocs
+= entsize
)
1294 Elf64_Mips_Internal_Rela rela
;
1295 boolean used_sym
, used_ssym
;
1298 if (entsize
== sizeof (Elf64_Mips_External_Rela
))
1299 mips_elf64_swap_reloca_in (abfd
,
1300 (Elf64_Mips_External_Rela
*) native_relocs
,
1304 Elf64_Mips_Internal_Rel rel
;
1306 mips_elf64_swap_reloc_in (abfd
,
1307 (Elf64_Mips_External_Rel
*) native_relocs
,
1309 rela
.r_offset
= rel
.r_offset
;
1310 rela
.r_sym
= rel
.r_sym
;
1311 rela
.r_ssym
= rel
.r_ssym
;
1312 rela
.r_type3
= rel
.r_type3
;
1313 rela
.r_type2
= rel
.r_type2
;
1314 rela
.r_type
= rel
.r_type
;
1318 /* Each entry represents up to three actual relocations. */
1322 for (ir
= 0; ir
< 3; ir
++)
1324 enum mips_elf64_reloc_type type
;
1331 type
= (enum mips_elf64_reloc_type
) rela
.r_type
;
1334 type
= (enum mips_elf64_reloc_type
) rela
.r_type2
;
1337 type
= (enum mips_elf64_reloc_type
) rela
.r_type3
;
1341 if (type
== R_MIPS_NONE
)
1343 /* There are no more relocations in this entry. If this
1344 is the first entry, we need to generate a dummy
1345 relocation so that the generic linker knows that
1346 there has been a break in the sequence of relocations
1347 applying to a particular address. */
1350 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
1351 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
1352 relent
->address
= rela
.r_offset
;
1354 relent
->address
= rela
.r_offset
- asect
->vma
;
1356 relent
->howto
= &howto_table
[(int) R_MIPS_NONE
];
1362 /* Some types require symbols, whereas some do not. */
1366 case R_MIPS_LITERAL
:
1367 case R_MIPS_INSERT_A
:
1368 case R_MIPS_INSERT_B
:
1370 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
1376 if (rela
.r_sym
== 0)
1377 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
1382 ps
= symbols
+ rela
.r_sym
- 1;
1384 if ((s
->flags
& BSF_SECTION_SYM
) == 0)
1385 relent
->sym_ptr_ptr
= ps
;
1387 relent
->sym_ptr_ptr
= s
->section
->symbol_ptr_ptr
;
1392 else if (! used_ssym
)
1394 switch (rela
.r_ssym
)
1397 relent
->sym_ptr_ptr
=
1398 bfd_abs_section_ptr
->symbol_ptr_ptr
;
1404 /* FIXME: I think these need to be handled using
1405 special howto structures. */
1417 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
1422 /* The address of an ELF reloc is section relative for an
1423 object file, and absolute for an executable file or
1424 shared library. The address of a BFD reloc is always
1425 section relative. */
1426 if ((abfd
->flags
& (EXEC_P
| DYNAMIC
)) == 0)
1427 relent
->address
= rela
.r_offset
;
1429 relent
->address
= rela
.r_offset
- asect
->vma
;
1431 relent
->addend
= rela
.r_addend
;
1433 relent
->howto
= &howto_table
[(int) type
];
1439 asect
->reloc_count
+= relent
- relents
;
1441 if (allocated
!= NULL
)
1447 if (allocated
!= NULL
)
1452 /* Read the relocations. On Irix 6, there can be two reloc sections
1453 associated with a single data section. */
1456 mips_elf64_slurp_reloc_table (abfd
, asect
, symbols
)
1461 struct bfd_elf_section_data
* const d
= elf_section_data (asect
);
1463 if (asect
->relocation
!= NULL
1464 || (asect
->flags
& SEC_RELOC
) == 0
1465 || asect
->reloc_count
== 0)
1468 /* Allocate space for 3 arelent structures for each Rel structure. */
1469 asect
->relocation
= ((arelent
*)
1471 asect
->reloc_count
* 3 * sizeof (arelent
)));
1472 if (asect
->relocation
== NULL
)
1475 /* The slurp_one_reloc_table routine increments reloc_count. */
1476 asect
->reloc_count
= 0;
1478 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
, symbols
, &d
->rel_hdr
))
1480 if (d
->rel_hdr2
!= NULL
)
1482 if (! mips_elf64_slurp_one_reloc_table (abfd
, asect
, symbols
,
1490 /* Write out the relocations. */
1493 mips_elf64_write_relocs (abfd
, sec
, data
)
1502 /* Handle a 64-bit MIPS ELF specific section. */
1505 mips_elf64_section_from_shdr (abfd
, hdr
, name
)
1507 Elf_Internal_Shdr
*hdr
;
1510 if (! _bfd_mips_elf_section_from_shdr (abfd
, hdr
, name
))
1516 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
1517 standard ELF. This structure is used to redirect the relocation
1518 handling routines. */
1520 const struct elf_size_info mips_elf64_size_info
=
1522 sizeof (Elf64_External_Ehdr
),
1523 sizeof (Elf64_External_Phdr
),
1524 sizeof (Elf64_External_Shdr
),
1525 sizeof (Elf64_Mips_External_Rel
),
1526 sizeof (Elf64_Mips_External_Rela
),
1527 sizeof (Elf64_External_Sym
),
1528 sizeof (Elf64_External_Dyn
),
1529 sizeof (Elf_External_Note
),
1534 bfd_elf64_write_out_phdrs
,
1535 bfd_elf64_write_shdrs_and_ehdr
,
1536 mips_elf64_write_relocs
,
1537 bfd_elf64_swap_symbol_out
,
1538 mips_elf64_slurp_reloc_table
,
1539 bfd_elf64_slurp_symbol_table
,
1540 bfd_elf64_swap_dyn_in
1543 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
1544 #define TARGET_LITTLE_NAME "elf64-littlemips"
1545 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
1546 #define TARGET_BIG_NAME "elf64-bigmips"
1547 #define ELF_ARCH bfd_arch_mips
1548 #define ELF_MACHINE_CODE EM_MIPS
1549 #define ELF_MAXPAGESIZE 0x1000
1550 #define elf_backend_size_info mips_elf64_size_info
1551 #define elf_backend_section_from_shdr mips_elf64_section_from_shdr
1552 #define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
1554 #include "elf64-target.h"