1 /* MIPS-specific support for 32-bit ELF
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 Most of the information added by Ian Lance Taylor, Cygnus Support,
7 N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
8 <mark@codesourcery.com>
9 Traditional MIPS targets support added by Koundinya.K, Dansk Data
10 Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
12 This file is part of BFD, the Binary File Descriptor library.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 /* This file handles MIPS ELF targets. SGI Irix 5 uses a slightly
29 different MIPS ELF from other targets. This matters when linking.
30 This file supports both, switching at runtime. */
38 #include "elfxx-mips.h"
41 /* Get the ECOFF swapping routines. */
43 #include "coff/symconst.h"
44 #include "coff/internal.h"
45 #include "coff/ecoff.h"
46 #include "coff/mips.h"
47 #define ECOFF_SIGNED_32
48 #include "ecoffswap.h"
50 static bfd_reloc_status_type mips_elf_generic_reloc
51 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
52 static bfd_reloc_status_type mips_elf_hi16_reloc
53 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
54 static bfd_reloc_status_type mips_elf_lo16_reloc
55 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
56 static bfd_reloc_status_type mips_elf_got16_reloc
57 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
58 static boolean mips_elf_assign_gp PARAMS ((bfd *, bfd_vma *));
59 static bfd_reloc_status_type mips_elf_final_gp
60 PARAMS ((bfd *, asymbol *, boolean, char **, bfd_vma *));
61 static bfd_reloc_status_type mips_elf_gprel16_reloc
62 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
63 static bfd_reloc_status_type mips_elf_literal_reloc
64 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
65 static bfd_reloc_status_type mips_elf_gprel32_reloc
66 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
67 static bfd_reloc_status_type gprel32_with_gp
68 PARAMS ((bfd *, asymbol *, arelent *, asection *, boolean, PTR, bfd_vma));
69 static bfd_reloc_status_type mips_elf_shift6_reloc
70 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
71 static bfd_reloc_status_type mips16_jump_reloc
72 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
73 static bfd_reloc_status_type mips16_gprel_reloc
74 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
75 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
76 PARAMS ((bfd *, bfd_reloc_code_real_type));
77 static reloc_howto_type *mips_elf_n32_rtype_to_howto
78 PARAMS ((unsigned int, boolean));
79 static void mips_info_to_howto_rel
80 PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
81 static void mips_info_to_howto_rela
82 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
83 static boolean mips_elf_sym_is_global PARAMS ((bfd *, asymbol *));
84 static boolean mips_elf_n32_object_p PARAMS ((bfd *));
85 static boolean elf32_mips_grok_prstatus
86 PARAMS ((bfd *, Elf_Internal_Note *));
87 static boolean elf32_mips_grok_psinfo
88 PARAMS ((bfd *, Elf_Internal_Note *));
89 static irix_compat_t elf_n32_mips_irix_compat
92 extern const bfd_target bfd_elf32_nbigmips_vec;
93 extern const bfd_target bfd_elf32_nlittlemips_vec;
95 static bfd_vma prev_reloc_address = -1;
96 static bfd_vma prev_reloc_addend = 0;
98 /* Nonzero if ABFD is using the N32 ABI. */
99 #define ABI_N32_P(abfd) \
100 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
102 /* Whether we are trying to be compatible with IRIX at all. */
103 #define SGI_COMPAT(abfd) \
104 (elf_n32_mips_irix_compat (abfd) != ict_none)
106 /* The number of local .got entries we reserve. */
107 #define MIPS_RESERVED_GOTNO (2)
109 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
110 from smaller values. Start with zero, widen, *then* decrement. */
111 #define MINUS_ONE (((bfd_vma)0) - 1)
113 /* The relocation table used for SHT_REL sections. */
115 static reloc_howto_type elf_mips_howto_table_rel[] =
118 HOWTO (R_MIPS_NONE, /* type */
120 0, /* size (0 = byte, 1 = short, 2 = long) */
122 false, /* pc_relative */
124 complain_overflow_dont, /* complain_on_overflow */
125 mips_elf_generic_reloc, /* special_function */
126 "R_MIPS_NONE", /* name */
127 false, /* partial_inplace */
130 false), /* pcrel_offset */
132 /* 16 bit relocation. */
133 HOWTO (R_MIPS_16, /* type */
135 2, /* size (0 = byte, 1 = short, 2 = long) */
137 false, /* pc_relative */
139 complain_overflow_signed, /* complain_on_overflow */
140 mips_elf_generic_reloc, /* special_function */
141 "R_MIPS_16", /* name */
142 true, /* partial_inplace */
143 0x0000ffff, /* src_mask */
144 0x0000ffff, /* dst_mask */
145 false), /* pcrel_offset */
147 /* 32 bit relocation. */
148 HOWTO (R_MIPS_32, /* type */
150 2, /* size (0 = byte, 1 = short, 2 = long) */
152 false, /* pc_relative */
154 complain_overflow_dont, /* complain_on_overflow */
155 mips_elf_generic_reloc, /* special_function */
156 "R_MIPS_32", /* name */
157 true, /* partial_inplace */
158 0xffffffff, /* src_mask */
159 0xffffffff, /* dst_mask */
160 false), /* pcrel_offset */
162 /* 32 bit symbol relative relocation. */
163 HOWTO (R_MIPS_REL32, /* type */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
167 false, /* pc_relative */
169 complain_overflow_dont, /* complain_on_overflow */
170 mips_elf_generic_reloc, /* special_function */
171 "R_MIPS_REL32", /* name */
172 true, /* partial_inplace */
173 0xffffffff, /* src_mask */
174 0xffffffff, /* dst_mask */
175 false), /* pcrel_offset */
177 /* 26 bit jump address. */
178 HOWTO (R_MIPS_26, /* type */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
182 false, /* pc_relative */
184 complain_overflow_dont, /* complain_on_overflow */
185 /* This needs complex overflow
186 detection, because the upper four
187 bits must match the PC + 4. */
188 mips_elf_generic_reloc, /* special_function */
189 "R_MIPS_26", /* name */
190 true, /* partial_inplace */
191 0x03ffffff, /* src_mask */
192 0x03ffffff, /* dst_mask */
193 false), /* pcrel_offset */
195 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
196 However, the native IRIX6 tools use them, so we try our best. */
198 /* High 16 bits of symbol value. */
199 HOWTO (R_MIPS_HI16, /* type */
201 2, /* size (0 = byte, 1 = short, 2 = long) */
203 false, /* pc_relative */
205 complain_overflow_dont, /* complain_on_overflow */
206 mips_elf_hi16_reloc, /* special_function */
207 "R_MIPS_HI16", /* name */
208 true, /* partial_inplace */
209 0x0000ffff, /* src_mask */
210 0x0000ffff, /* dst_mask */
211 false), /* pcrel_offset */
213 /* Low 16 bits of symbol value. */
214 HOWTO (R_MIPS_LO16, /* type */
216 2, /* size (0 = byte, 1 = short, 2 = long) */
218 false, /* pc_relative */
220 complain_overflow_dont, /* complain_on_overflow */
221 mips_elf_lo16_reloc, /* special_function */
222 "R_MIPS_LO16", /* name */
223 true, /* partial_inplace */
224 0x0000ffff, /* src_mask */
225 0x0000ffff, /* dst_mask */
226 false), /* pcrel_offset */
228 /* GP relative reference. */
229 HOWTO (R_MIPS_GPREL16, /* type */
231 2, /* size (0 = byte, 1 = short, 2 = long) */
233 false, /* pc_relative */
235 complain_overflow_signed, /* complain_on_overflow */
236 mips_elf_gprel16_reloc, /* special_function */
237 "R_MIPS_GPREL16", /* name */
238 true, /* partial_inplace */
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
241 false), /* pcrel_offset */
243 /* Reference to literal section. */
244 HOWTO (R_MIPS_LITERAL, /* type */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
248 false, /* pc_relative */
250 complain_overflow_signed, /* complain_on_overflow */
251 mips_elf_literal_reloc, /* special_function */
252 "R_MIPS_LITERAL", /* name */
253 true, /* partial_inplace */
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
256 false), /* pcrel_offset */
258 /* Reference to global offset table. */
259 HOWTO (R_MIPS_GOT16, /* type */
261 2, /* size (0 = byte, 1 = short, 2 = long) */
263 false, /* pc_relative */
265 complain_overflow_signed, /* complain_on_overflow */
266 mips_elf_got16_reloc, /* special_function */
267 "R_MIPS_GOT16", /* name */
268 true, /* partial_inplace */
269 0x0000ffff, /* src_mask */
270 0x0000ffff, /* dst_mask */
271 false), /* pcrel_offset */
273 /* 16 bit PC relative reference. */
274 HOWTO (R_MIPS_PC16, /* type */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
278 true, /* pc_relative */
280 complain_overflow_signed, /* complain_on_overflow */
281 mips_elf_generic_reloc, /* special_function */
282 "R_MIPS_PC16", /* name */
283 true, /* partial_inplace */
284 0x0000ffff, /* src_mask */
285 0x0000ffff, /* dst_mask */
286 true), /* pcrel_offset */
288 /* 16 bit call through global offset table. */
289 HOWTO (R_MIPS_CALL16, /* type */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
293 false, /* pc_relative */
295 complain_overflow_signed, /* complain_on_overflow */
296 mips_elf_generic_reloc, /* special_function */
297 "R_MIPS_CALL16", /* name */
298 true, /* partial_inplace */
299 0x0000ffff, /* src_mask */
300 0x0000ffff, /* dst_mask */
301 false), /* pcrel_offset */
303 /* 32 bit GP relative reference. */
304 HOWTO (R_MIPS_GPREL32, /* type */
306 2, /* size (0 = byte, 1 = short, 2 = long) */
308 false, /* pc_relative */
310 complain_overflow_dont, /* complain_on_overflow */
311 mips_elf_gprel32_reloc, /* special_function */
312 "R_MIPS_GPREL32", /* name */
313 true, /* partial_inplace */
314 0xffffffff, /* src_mask */
315 0xffffffff, /* dst_mask */
316 false), /* pcrel_offset */
318 /* The remaining relocs are defined on Irix 5, although they are
319 not defined by the ABI. */
324 /* A 5 bit shift field. */
325 HOWTO (R_MIPS_SHIFT5, /* type */
327 2, /* size (0 = byte, 1 = short, 2 = long) */
329 false, /* pc_relative */
331 complain_overflow_bitfield, /* complain_on_overflow */
332 mips_elf_generic_reloc, /* special_function */
333 "R_MIPS_SHIFT5", /* name */
334 true, /* partial_inplace */
335 0x000007c0, /* src_mask */
336 0x000007c0, /* dst_mask */
337 false), /* pcrel_offset */
339 /* A 6 bit shift field. */
340 HOWTO (R_MIPS_SHIFT6, /* type */
342 2, /* size (0 = byte, 1 = short, 2 = long) */
344 false, /* pc_relative */
346 complain_overflow_bitfield, /* complain_on_overflow */
347 mips_elf_shift6_reloc, /* special_function */
348 "R_MIPS_SHIFT6", /* name */
349 true, /* partial_inplace */
350 0x000007c4, /* src_mask */
351 0x000007c4, /* dst_mask */
352 false), /* pcrel_offset */
354 /* A 64 bit relocation. */
355 HOWTO (R_MIPS_64, /* type */
357 4, /* size (0 = byte, 1 = short, 2 = long) */
359 false, /* pc_relative */
361 complain_overflow_dont, /* complain_on_overflow */
362 mips_elf_generic_reloc, /* special_function */
363 "R_MIPS_64", /* name */
364 true, /* partial_inplace */
365 MINUS_ONE, /* src_mask */
366 MINUS_ONE, /* dst_mask */
367 false), /* pcrel_offset */
369 /* Displacement in the global offset table. */
370 HOWTO (R_MIPS_GOT_DISP, /* type */
372 2, /* size (0 = byte, 1 = short, 2 = long) */
374 false, /* pc_relative */
376 complain_overflow_signed, /* complain_on_overflow */
377 mips_elf_generic_reloc, /* special_function */
378 "R_MIPS_GOT_DISP", /* name */
379 true, /* partial_inplace */
380 0x0000ffff, /* src_mask */
381 0x0000ffff, /* dst_mask */
382 false), /* pcrel_offset */
384 /* Displacement to page pointer in the global offset table. */
385 HOWTO (R_MIPS_GOT_PAGE, /* type */
387 2, /* size (0 = byte, 1 = short, 2 = long) */
389 false, /* pc_relative */
391 complain_overflow_signed, /* complain_on_overflow */
392 mips_elf_generic_reloc, /* special_function */
393 "R_MIPS_GOT_PAGE", /* name */
394 true, /* partial_inplace */
395 0x0000ffff, /* src_mask */
396 0x0000ffff, /* dst_mask */
397 false), /* pcrel_offset */
399 /* Offset from page pointer in the global offset table. */
400 HOWTO (R_MIPS_GOT_OFST, /* type */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
404 false, /* pc_relative */
406 complain_overflow_signed, /* complain_on_overflow */
407 mips_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 HOWTO (R_MIPS_GOT_HI16, /* type */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
419 false, /* pc_relative */
421 complain_overflow_dont, /* complain_on_overflow */
422 mips_elf_generic_reloc, /* special_function */
423 "R_MIPS_GOT_HI16", /* name */
424 true, /* partial_inplace */
425 0x0000ffff, /* src_mask */
426 0x0000ffff, /* dst_mask */
427 false), /* pcrel_offset */
429 /* Low 16 bits of displacement in global offset table. */
430 HOWTO (R_MIPS_GOT_LO16, /* type */
432 2, /* size (0 = byte, 1 = short, 2 = long) */
434 false, /* pc_relative */
436 complain_overflow_dont, /* complain_on_overflow */
437 mips_elf_generic_reloc, /* special_function */
438 "R_MIPS_GOT_LO16", /* name */
439 true, /* partial_inplace */
440 0x0000ffff, /* src_mask */
441 0x0000ffff, /* dst_mask */
442 false), /* pcrel_offset */
444 /* 64 bit subtraction. */
445 HOWTO (R_MIPS_SUB, /* type */
447 4, /* size (0 = byte, 1 = short, 2 = long) */
449 false, /* pc_relative */
451 complain_overflow_dont, /* complain_on_overflow */
452 mips_elf_generic_reloc, /* special_function */
453 "R_MIPS_SUB", /* name */
454 true, /* partial_inplace */
455 MINUS_ONE, /* src_mask */
456 MINUS_ONE, /* dst_mask */
457 false), /* pcrel_offset */
459 /* Insert the addend as an instruction. */
460 /* FIXME: Not handled correctly. */
461 HOWTO (R_MIPS_INSERT_A, /* type */
463 2, /* size (0 = byte, 1 = short, 2 = long) */
465 false, /* pc_relative */
467 complain_overflow_dont, /* complain_on_overflow */
468 mips_elf_generic_reloc, /* special_function */
469 "R_MIPS_INSERT_A", /* name */
470 true, /* partial_inplace */
471 0xffffffff, /* src_mask */
472 0xffffffff, /* dst_mask */
473 false), /* pcrel_offset */
475 /* Insert the addend as an instruction, and change all relocations
476 to refer to the old instruction at the address. */
477 /* FIXME: Not handled correctly. */
478 HOWTO (R_MIPS_INSERT_B, /* type */
480 2, /* size (0 = byte, 1 = short, 2 = long) */
482 false, /* pc_relative */
484 complain_overflow_dont, /* complain_on_overflow */
485 mips_elf_generic_reloc, /* special_function */
486 "R_MIPS_INSERT_B", /* name */
487 true, /* partial_inplace */
488 0xffffffff, /* src_mask */
489 0xffffffff, /* dst_mask */
490 false), /* pcrel_offset */
492 /* Delete a 32 bit instruction. */
493 /* FIXME: Not handled correctly. */
494 HOWTO (R_MIPS_DELETE, /* type */
496 2, /* size (0 = byte, 1 = short, 2 = long) */
498 false, /* pc_relative */
500 complain_overflow_dont, /* complain_on_overflow */
501 mips_elf_generic_reloc, /* special_function */
502 "R_MIPS_DELETE", /* name */
503 true, /* partial_inplace */
504 0xffffffff, /* src_mask */
505 0xffffffff, /* dst_mask */
506 false), /* pcrel_offset */
508 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
510 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
511 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
513 b) No other NEwABI toolchain actually emits such relocations. */
514 EMPTY_HOWTO (R_MIPS_HIGHER),
515 EMPTY_HOWTO (R_MIPS_HIGHEST),
517 /* High 16 bits of displacement in global offset table. */
518 HOWTO (R_MIPS_CALL_HI16, /* type */
520 2, /* size (0 = byte, 1 = short, 2 = long) */
522 false, /* pc_relative */
524 complain_overflow_dont, /* complain_on_overflow */
525 mips_elf_generic_reloc, /* special_function */
526 "R_MIPS_CALL_HI16", /* name */
527 true, /* partial_inplace */
528 0x0000ffff, /* src_mask */
529 0x0000ffff, /* dst_mask */
530 false), /* pcrel_offset */
532 /* Low 16 bits of displacement in global offset table. */
533 HOWTO (R_MIPS_CALL_LO16, /* type */
535 2, /* size (0 = byte, 1 = short, 2 = long) */
537 false, /* pc_relative */
539 complain_overflow_dont, /* complain_on_overflow */
540 mips_elf_generic_reloc, /* special_function */
541 "R_MIPS_CALL_LO16", /* name */
542 true, /* partial_inplace */
543 0x0000ffff, /* src_mask */
544 0x0000ffff, /* dst_mask */
545 false), /* pcrel_offset */
547 /* Section displacement. */
548 HOWTO (R_MIPS_SCN_DISP, /* type */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
552 false, /* pc_relative */
554 complain_overflow_dont, /* complain_on_overflow */
555 mips_elf_generic_reloc, /* special_function */
556 "R_MIPS_SCN_DISP", /* name */
557 true, /* partial_inplace */
558 0xffffffff, /* src_mask */
559 0xffffffff, /* dst_mask */
560 false), /* pcrel_offset */
562 HOWTO (R_MIPS_REL16, /* type */
564 1, /* size (0 = byte, 1 = short, 2 = long) */
566 false, /* pc_relative */
568 complain_overflow_signed, /* complain_on_overflow */
569 mips_elf_generic_reloc, /* special_function */
570 "R_MIPS_REL16", /* name */
571 true, /* partial_inplace */
572 0xffff, /* src_mask */
573 0xffff, /* dst_mask */
574 false), /* pcrel_offset */
576 /* These two are obsolete. */
577 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
578 EMPTY_HOWTO (R_MIPS_PJUMP),
580 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
581 It must be used for multigot GOT's (and only there). */
582 HOWTO (R_MIPS_RELGOT, /* type */
584 2, /* size (0 = byte, 1 = short, 2 = long) */
586 false, /* pc_relative */
588 complain_overflow_dont, /* complain_on_overflow */
589 mips_elf_generic_reloc, /* special_function */
590 "R_MIPS_RELGOT", /* name */
591 true, /* partial_inplace */
592 0xffffffff, /* src_mask */
593 0xffffffff, /* dst_mask */
594 false), /* pcrel_offset */
596 /* Protected jump conversion. This is an optimization hint. No
597 relocation is required for correctness. */
598 HOWTO (R_MIPS_JALR, /* type */
600 2, /* size (0 = byte, 1 = short, 2 = long) */
602 false, /* pc_relative */
604 complain_overflow_dont, /* complain_on_overflow */
605 mips_elf_generic_reloc, /* special_function */
606 "R_MIPS_JALR", /* name */
607 false, /* partial_inplace */
608 0x00000000, /* src_mask */
609 0x00000000, /* dst_mask */
610 false), /* pcrel_offset */
613 /* The relocation table used for SHT_RELA sections. */
615 static reloc_howto_type elf_mips_howto_table_rela[] =
618 HOWTO (R_MIPS_NONE, /* type */
620 0, /* size (0 = byte, 1 = short, 2 = long) */
622 false, /* pc_relative */
624 complain_overflow_dont, /* complain_on_overflow */
625 mips_elf_generic_reloc, /* special_function */
626 "R_MIPS_NONE", /* name */
627 false, /* partial_inplace */
630 false), /* pcrel_offset */
632 /* 16 bit relocation. */
633 HOWTO (R_MIPS_16, /* type */
635 2, /* size (0 = byte, 1 = short, 2 = long) */
637 false, /* pc_relative */
639 complain_overflow_signed, /* complain_on_overflow */
640 mips_elf_generic_reloc, /* special_function */
641 "R_MIPS_16", /* name */
642 false, /* partial_inplace */
644 0x0000, /* dst_mask */
645 false), /* pcrel_offset */
647 /* 32 bit relocation. */
648 HOWTO (R_MIPS_32, /* type */
650 2, /* size (0 = byte, 1 = short, 2 = long) */
652 false, /* pc_relative */
654 complain_overflow_dont, /* complain_on_overflow */
655 mips_elf_generic_reloc, /* special_function */
656 "R_MIPS_32", /* name */
657 false, /* partial_inplace */
659 0xffffffff, /* dst_mask */
660 false), /* pcrel_offset */
662 /* 32 bit symbol relative relocation. */
663 HOWTO (R_MIPS_REL32, /* type */
665 2, /* size (0 = byte, 1 = short, 2 = long) */
667 false, /* pc_relative */
669 complain_overflow_dont, /* complain_on_overflow */
670 mips_elf_generic_reloc, /* special_function */
671 "R_MIPS_REL32", /* name */
672 false, /* partial_inplace */
674 0xffffffff, /* dst_mask */
675 false), /* pcrel_offset */
677 /* 26 bit jump address. */
678 HOWTO (R_MIPS_26, /* type */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
682 false, /* pc_relative */
684 complain_overflow_dont, /* complain_on_overflow */
685 /* This needs complex overflow
686 detection, because the upper 36
687 bits must match the PC + 4. */
688 mips_elf_generic_reloc, /* special_function */
689 "R_MIPS_26", /* name */
690 false, /* partial_inplace */
692 0x03ffffff, /* dst_mask */
693 false), /* pcrel_offset */
695 /* High 16 bits of symbol value. */
696 HOWTO (R_MIPS_HI16, /* type */
698 2, /* size (0 = byte, 1 = short, 2 = long) */
700 false, /* pc_relative */
702 complain_overflow_dont, /* complain_on_overflow */
703 mips_elf_generic_reloc, /* special_function */
704 "R_MIPS_HI16", /* name */
705 false, /* partial_inplace */
707 0x0000ffff, /* dst_mask */
708 false), /* pcrel_offset */
710 /* Low 16 bits of symbol value. */
711 HOWTO (R_MIPS_LO16, /* type */
713 2, /* size (0 = byte, 1 = short, 2 = long) */
715 false, /* pc_relative */
717 complain_overflow_dont, /* complain_on_overflow */
718 mips_elf_generic_reloc, /* special_function */
719 "R_MIPS_LO16", /* name */
720 false, /* partial_inplace */
722 0x0000ffff, /* dst_mask */
723 false), /* pcrel_offset */
725 /* GP relative reference. */
726 HOWTO (R_MIPS_GPREL16, /* type */
728 2, /* size (0 = byte, 1 = short, 2 = long) */
730 false, /* pc_relative */
732 complain_overflow_signed, /* complain_on_overflow */
733 mips_elf_gprel16_reloc, /* special_function */
734 "R_MIPS_GPREL16", /* name */
735 false, /* partial_inplace */
737 0x0000ffff, /* dst_mask */
738 false), /* pcrel_offset */
740 /* Reference to literal section. */
741 HOWTO (R_MIPS_LITERAL, /* type */
743 2, /* size (0 = byte, 1 = short, 2 = long) */
745 false, /* pc_relative */
747 complain_overflow_signed, /* complain_on_overflow */
748 mips_elf_literal_reloc, /* special_function */
749 "R_MIPS_LITERAL", /* name */
750 false, /* partial_inplace */
752 0x0000ffff, /* dst_mask */
753 false), /* pcrel_offset */
755 /* Reference to global offset table. */
756 HOWTO (R_MIPS_GOT16, /* type */
758 2, /* size (0 = byte, 1 = short, 2 = long) */
760 false, /* pc_relative */
762 complain_overflow_signed, /* complain_on_overflow */
763 mips_elf_got16_reloc, /* special_function */
764 "R_MIPS_GOT16", /* name */
765 false, /* partial_inplace */
767 0x0000ffff, /* dst_mask */
768 false), /* pcrel_offset */
770 /* 16 bit PC relative reference. */
771 HOWTO (R_MIPS_PC16, /* type */
773 2, /* size (0 = byte, 1 = short, 2 = long) */
775 true, /* pc_relative */
777 complain_overflow_signed, /* complain_on_overflow */
778 mips_elf_generic_reloc, /* special_function */
779 "R_MIPS_PC16", /* name */
780 false, /* partial_inplace */
782 0x0000ffff, /* dst_mask */
783 true), /* pcrel_offset */
785 /* 16 bit call through global offset table. */
786 HOWTO (R_MIPS_CALL16, /* type */
788 2, /* size (0 = byte, 1 = short, 2 = long) */
790 false, /* pc_relative */
792 complain_overflow_signed, /* complain_on_overflow */
793 mips_elf_generic_reloc, /* special_function */
794 "R_MIPS_CALL16", /* name */
795 false, /* partial_inplace */
797 0x0000ffff, /* dst_mask */
798 false), /* pcrel_offset */
800 /* 32 bit GP relative reference. */
801 HOWTO (R_MIPS_GPREL32, /* type */
803 2, /* size (0 = byte, 1 = short, 2 = long) */
805 false, /* pc_relative */
807 complain_overflow_dont, /* complain_on_overflow */
808 mips_elf_gprel32_reloc, /* special_function */
809 "R_MIPS_GPREL32", /* name */
810 false, /* partial_inplace */
812 0xffffffff, /* dst_mask */
813 false), /* pcrel_offset */
819 /* A 5 bit shift field. */
820 HOWTO (R_MIPS_SHIFT5, /* type */
822 2, /* size (0 = byte, 1 = short, 2 = long) */
824 false, /* pc_relative */
826 complain_overflow_bitfield, /* complain_on_overflow */
827 mips_elf_generic_reloc, /* special_function */
828 "R_MIPS_SHIFT5", /* name */
829 false, /* partial_inplace */
831 0x000007c0, /* dst_mask */
832 false), /* pcrel_offset */
834 /* A 6 bit shift field. */
835 HOWTO (R_MIPS_SHIFT6, /* type */
837 2, /* size (0 = byte, 1 = short, 2 = long) */
839 false, /* pc_relative */
841 complain_overflow_bitfield, /* complain_on_overflow */
842 mips_elf_shift6_reloc, /* special_function */
843 "R_MIPS_SHIFT6", /* name */
844 false, /* partial_inplace */
846 0x000007c4, /* dst_mask */
847 false), /* pcrel_offset */
849 /* 64 bit relocation. */
850 HOWTO (R_MIPS_64, /* type */
852 4, /* size (0 = byte, 1 = short, 2 = long) */
854 false, /* pc_relative */
856 complain_overflow_dont, /* complain_on_overflow */
857 mips_elf_generic_reloc, /* special_function */
858 "R_MIPS_64", /* name */
859 false, /* partial_inplace */
861 MINUS_ONE, /* dst_mask */
862 false), /* pcrel_offset */
864 /* Displacement in the global offset table. */
865 HOWTO (R_MIPS_GOT_DISP, /* type */
867 2, /* size (0 = byte, 1 = short, 2 = long) */
869 false, /* pc_relative */
871 complain_overflow_signed, /* complain_on_overflow */
872 mips_elf_generic_reloc, /* special_function */
873 "R_MIPS_GOT_DISP", /* name */
874 false, /* partial_inplace */
876 0x0000ffff, /* dst_mask */
877 false), /* pcrel_offset */
879 /* Displacement to page pointer in the global offset table. */
880 HOWTO (R_MIPS_GOT_PAGE, /* type */
882 2, /* size (0 = byte, 1 = short, 2 = long) */
884 false, /* pc_relative */
886 complain_overflow_signed, /* complain_on_overflow */
887 mips_elf_generic_reloc, /* special_function */
888 "R_MIPS_GOT_PAGE", /* name */
889 false, /* partial_inplace */
891 0x0000ffff, /* dst_mask */
892 false), /* pcrel_offset */
894 /* Offset from page pointer in the global offset table. */
895 HOWTO (R_MIPS_GOT_OFST, /* type */
897 2, /* size (0 = byte, 1 = short, 2 = long) */
899 false, /* pc_relative */
901 complain_overflow_signed, /* complain_on_overflow */
902 mips_elf_generic_reloc, /* special_function */
903 "R_MIPS_GOT_OFST", /* name */
904 false, /* partial_inplace */
906 0x0000ffff, /* dst_mask */
907 false), /* pcrel_offset */
909 /* High 16 bits of displacement in global offset table. */
910 HOWTO (R_MIPS_GOT_HI16, /* type */
912 2, /* size (0 = byte, 1 = short, 2 = long) */
914 false, /* pc_relative */
916 complain_overflow_dont, /* complain_on_overflow */
917 mips_elf_generic_reloc, /* special_function */
918 "R_MIPS_GOT_HI16", /* name */
919 false, /* partial_inplace */
921 0x0000ffff, /* dst_mask */
922 false), /* pcrel_offset */
924 /* Low 16 bits of displacement in global offset table. */
925 HOWTO (R_MIPS_GOT_LO16, /* type */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
929 false, /* pc_relative */
931 complain_overflow_dont, /* complain_on_overflow */
932 mips_elf_generic_reloc, /* special_function */
933 "R_MIPS_GOT_LO16", /* name */
934 false, /* partial_inplace */
936 0x0000ffff, /* dst_mask */
937 false), /* pcrel_offset */
939 /* 64 bit substraction. */
940 HOWTO (R_MIPS_SUB, /* type */
942 4, /* size (0 = byte, 1 = short, 2 = long) */
944 false, /* pc_relative */
946 complain_overflow_dont, /* complain_on_overflow */
947 mips_elf_generic_reloc, /* special_function */
948 "R_MIPS_SUB", /* name */
949 false, /* partial_inplace */
951 MINUS_ONE, /* dst_mask */
952 false), /* pcrel_offset */
954 /* Insert the addend as an instruction. */
955 /* FIXME: Not handled correctly. */
956 HOWTO (R_MIPS_INSERT_A, /* type */
958 2, /* size (0 = byte, 1 = short, 2 = long) */
960 false, /* pc_relative */
962 complain_overflow_dont, /* complain_on_overflow */
963 mips_elf_generic_reloc, /* special_function */
964 "R_MIPS_INSERT_A", /* name */
965 false, /* partial_inplace */
967 0xffffffff, /* dst_mask */
968 false), /* pcrel_offset */
970 /* Insert the addend as an instruction, and change all relocations
971 to refer to the old instruction at the address. */
972 /* FIXME: Not handled correctly. */
973 HOWTO (R_MIPS_INSERT_B, /* type */
975 2, /* size (0 = byte, 1 = short, 2 = long) */
977 false, /* pc_relative */
979 complain_overflow_dont, /* complain_on_overflow */
980 mips_elf_generic_reloc, /* special_function */
981 "R_MIPS_INSERT_B", /* name */
982 false, /* partial_inplace */
984 0xffffffff, /* dst_mask */
985 false), /* pcrel_offset */
987 /* Delete a 32 bit instruction. */
988 /* FIXME: Not handled correctly. */
989 HOWTO (R_MIPS_DELETE, /* type */
991 2, /* size (0 = byte, 1 = short, 2 = long) */
993 false, /* pc_relative */
995 complain_overflow_dont, /* complain_on_overflow */
996 mips_elf_generic_reloc, /* special_function */
997 "R_MIPS_DELETE", /* name */
998 false, /* partial_inplace */
1000 0xffffffff, /* dst_mask */
1001 false), /* pcrel_offset */
1003 /* Get the higher value of a 64 bit addend. */
1004 HOWTO (R_MIPS_HIGHER, /* type */
1006 2, /* size (0 = byte, 1 = short, 2 = long) */
1008 false, /* pc_relative */
1010 complain_overflow_dont, /* complain_on_overflow */
1011 mips_elf_generic_reloc, /* special_function */
1012 "R_MIPS_HIGHER", /* name */
1013 false, /* partial_inplace */
1015 0x0000ffff, /* dst_mask */
1016 false), /* pcrel_offset */
1018 /* Get the highest value of a 64 bit addend. */
1019 HOWTO (R_MIPS_HIGHEST, /* type */
1021 2, /* size (0 = byte, 1 = short, 2 = long) */
1023 false, /* pc_relative */
1025 complain_overflow_dont, /* complain_on_overflow */
1026 mips_elf_generic_reloc, /* special_function */
1027 "R_MIPS_HIGHEST", /* name */
1028 false, /* partial_inplace */
1030 0x0000ffff, /* dst_mask */
1031 false), /* pcrel_offset */
1033 /* High 16 bits of displacement in global offset table. */
1034 HOWTO (R_MIPS_CALL_HI16, /* type */
1036 2, /* size (0 = byte, 1 = short, 2 = long) */
1038 false, /* pc_relative */
1040 complain_overflow_dont, /* complain_on_overflow */
1041 mips_elf_generic_reloc, /* special_function */
1042 "R_MIPS_CALL_HI16", /* name */
1043 false, /* partial_inplace */
1045 0x0000ffff, /* dst_mask */
1046 false), /* pcrel_offset */
1048 /* Low 16 bits of displacement in global offset table. */
1049 HOWTO (R_MIPS_CALL_LO16, /* type */
1051 2, /* size (0 = byte, 1 = short, 2 = long) */
1053 false, /* pc_relative */
1055 complain_overflow_dont, /* complain_on_overflow */
1056 mips_elf_generic_reloc, /* special_function */
1057 "R_MIPS_CALL_LO16", /* name */
1058 false, /* partial_inplace */
1060 0x0000ffff, /* dst_mask */
1061 false), /* pcrel_offset */
1063 /* Section displacement, used by an associated event location section. */
1064 HOWTO (R_MIPS_SCN_DISP, /* type */
1066 2, /* size (0 = byte, 1 = short, 2 = long) */
1068 false, /* pc_relative */
1070 complain_overflow_dont, /* complain_on_overflow */
1071 mips_elf_generic_reloc, /* special_function */
1072 "R_MIPS_SCN_DISP", /* name */
1073 false, /* partial_inplace */
1075 0xffffffff, /* dst_mask */
1076 false), /* pcrel_offset */
1078 /* 16 bit relocation. */
1079 HOWTO (R_MIPS_REL16, /* type */
1081 1, /* size (0 = byte, 1 = short, 2 = long) */
1083 false, /* pc_relative */
1085 complain_overflow_signed, /* complain_on_overflow */
1086 mips_elf_generic_reloc, /* special_function */
1087 "R_MIPS_REL16", /* name */
1088 false, /* partial_inplace */
1090 0xffff, /* dst_mask */
1091 false), /* pcrel_offset */
1093 /* These two are obsolete. */
1094 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1095 EMPTY_HOWTO (R_MIPS_PJUMP),
1097 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1098 It must be used for multigot GOT's (and only there). */
1099 HOWTO (R_MIPS_RELGOT, /* type */
1101 2, /* size (0 = byte, 1 = short, 2 = long) */
1103 false, /* pc_relative */
1105 complain_overflow_dont, /* complain_on_overflow */
1106 mips_elf_generic_reloc, /* special_function */
1107 "R_MIPS_RELGOT", /* name */
1108 false, /* partial_inplace */
1110 0xffffffff, /* dst_mask */
1111 false), /* pcrel_offset */
1113 /* Protected jump conversion. This is an optimization hint. No
1114 relocation is required for correctness. */
1115 HOWTO (R_MIPS_JALR, /* type */
1117 2, /* size (0 = byte, 1 = short, 2 = long) */
1119 false, /* pc_relative */
1121 complain_overflow_dont, /* complain_on_overflow */
1122 mips_elf_generic_reloc, /* special_function */
1123 "R_MIPS_JALR", /* name */
1124 false, /* partial_inplace */
1126 0xffffffff, /* dst_mask */
1127 false), /* pcrel_offset */
1130 /* The reloc used for the mips16 jump instruction. */
1131 static reloc_howto_type elf_mips16_jump_howto =
1132 HOWTO (R_MIPS16_26, /* type */
1134 2, /* size (0 = byte, 1 = short, 2 = long) */
1136 false, /* pc_relative */
1138 complain_overflow_dont, /* complain_on_overflow */
1139 /* This needs complex overflow
1140 detection, because the upper four
1141 bits must match the PC. */
1142 mips16_jump_reloc, /* special_function */
1143 "R_MIPS16_26", /* name */
1144 true, /* partial_inplace */
1145 0x3ffffff, /* src_mask */
1146 0x3ffffff, /* dst_mask */
1147 false); /* pcrel_offset */
1149 /* The reloc used for the mips16 gprel instruction. */
1150 static reloc_howto_type elf_mips16_gprel_howto =
1151 HOWTO (R_MIPS16_GPREL, /* type */
1153 2, /* size (0 = byte, 1 = short, 2 = long) */
1155 false, /* pc_relative */
1157 complain_overflow_signed, /* complain_on_overflow */
1158 mips16_gprel_reloc, /* special_function */
1159 "R_MIPS16_GPREL", /* name */
1160 true, /* partial_inplace */
1161 0x07ff001f, /* src_mask */
1162 0x07ff001f, /* dst_mask */
1163 false); /* pcrel_offset */
1165 /* GNU extension to record C++ vtable hierarchy */
1166 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1167 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1169 2, /* size (0 = byte, 1 = short, 2 = long) */
1171 false, /* pc_relative */
1173 complain_overflow_dont, /* complain_on_overflow */
1174 NULL, /* special_function */
1175 "R_MIPS_GNU_VTINHERIT", /* name */
1176 false, /* partial_inplace */
1179 false); /* pcrel_offset */
1181 /* GNU extension to record C++ vtable member usage */
1182 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1183 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1185 2, /* size (0 = byte, 1 = short, 2 = long) */
1187 false, /* pc_relative */
1189 complain_overflow_dont, /* complain_on_overflow */
1190 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1191 "R_MIPS_GNU_VTENTRY", /* name */
1192 false, /* partial_inplace */
1195 false); /* pcrel_offset */
1197 /* This is derived from bfd_elf_generic_reloc. NewABI allows us to have
1198 several relocations against the same address. The addend is derived
1199 from the addends of preceding relocations. If we don't need to
1200 do something special, we simply keep track of the addend. */
1202 #define GET_RELOC_ADDEND(obfd, sym, entry, sec) \
1204 /* If we're relocating, and this is an external symbol, we don't \
1205 want to change anything. */ \
1206 if (obfd != (bfd *) NULL \
1207 && (sym->flags & BSF_SECTION_SYM) == 0 \
1208 && (! entry->howto->partial_inplace \
1209 || entry->addend == 0)) \
1211 entry->address += sec->output_offset; \
1212 return bfd_reloc_ok; \
1215 /* The addend of combined relocs is remembered and left for \
1216 subsequent relocs. */ \
1217 if (prev_reloc_address != reloc_entry->address) \
1219 prev_reloc_address = reloc_entry->address; \
1220 prev_reloc_addend = reloc_entry->addend; \
1223 reloc_entry->addend = prev_reloc_addend; \
1226 #define SET_RELOC_ADDEND(entry) \
1228 prev_reloc_addend = entry->addend; \
1231 static bfd_reloc_status_type
1232 mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section,
1233 output_bfd, error_message)
1234 bfd *abfd ATTRIBUTE_UNUSED;
1235 arelent *reloc_entry;
1237 PTR data ATTRIBUTE_UNUSED;
1238 asection *input_section;
1240 char **error_message ATTRIBUTE_UNUSED;
1242 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1244 return bfd_reloc_continue;
1247 /* Do a R_MIPS_HI16 relocation. This has to be done in combination
1248 with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
1249 the HI16. Here we just save the information we need; we do the
1250 actual relocation when we see the LO16.
1252 MIPS ELF requires that the LO16 immediately follow the HI16. As a
1253 GNU extension, for non-pc-relative relocations, we permit an
1254 arbitrary number of HI16 relocs to be associated with a single LO16
1255 reloc. This extension permits gcc to output the HI and LO relocs
1258 This cannot be done for PC-relative relocations because both the HI16
1259 and LO16 parts of the relocations must be done relative to the LO16
1260 part, and there can be carry to or borrow from the HI16 part. */
1264 struct mips_hi16 *next;
1269 /* FIXME: This should not be a static variable. */
1271 static struct mips_hi16 *mips_hi16_list;
1273 static bfd_reloc_status_type
1274 mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data, input_section,
1275 output_bfd, error_message)
1276 bfd *abfd ATTRIBUTE_UNUSED;
1277 arelent *reloc_entry;
1280 asection *input_section;
1282 char **error_message ATTRIBUTE_UNUSED;
1284 bfd_reloc_status_type ret;
1286 struct mips_hi16 *n;
1288 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1292 if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
1293 ret = bfd_reloc_undefined;
1295 if (bfd_is_com_section (symbol->section))
1298 relocation = symbol->value;
1300 relocation += symbol->section->output_section->vma;
1301 relocation += symbol->section->output_offset;
1302 relocation += reloc_entry->addend;
1304 if (reloc_entry->address > input_section->_cooked_size)
1305 return bfd_reloc_outofrange;
1307 /* Save the information, and let LO16 do the actual relocation. */
1308 n = (struct mips_hi16 *) bfd_malloc ((bfd_size_type) sizeof *n);
1310 return bfd_reloc_outofrange;
1311 n->addr = (bfd_byte *) data + reloc_entry->address;
1312 n->addend = relocation;
1313 n->next = mips_hi16_list;
1316 if (output_bfd != (bfd *) NULL)
1317 reloc_entry->address += input_section->output_offset;
1322 /* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit
1323 inplace relocation; this function exists in order to do the
1324 R_MIPS_HI16 relocation described above. */
1326 static bfd_reloc_status_type
1327 mips_elf_lo16_reloc (abfd, reloc_entry, symbol, data, input_section,
1328 output_bfd, error_message)
1330 arelent *reloc_entry;
1333 asection *input_section;
1335 char **error_message;
1337 if (mips_hi16_list != NULL)
1339 struct mips_hi16 *l;
1346 unsigned long vallo;
1347 struct mips_hi16 *next;
1349 /* Do the HI16 relocation. Note that we actually don't need
1350 to know anything about the LO16 itself, except where to
1351 find the low 16 bits of the addend needed by the LO16. */
1352 insn = bfd_get_32 (abfd, l->addr);
1353 vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1355 /* The low order 16 bits are always treated as a signed
1357 vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
1358 val = ((insn & 0xffff) << 16) + vallo;
1361 /* If PC-relative, we need to subtract out the address of the LO
1362 half of the HI/LO. (The actual relocation is relative
1363 to that instruction.) */
1364 if (reloc_entry->howto->pc_relative)
1365 val -= reloc_entry->address;
1367 /* At this point, "val" has the value of the combined HI/LO
1368 pair. If the low order 16 bits (which will be used for
1369 the LO16 insn) are negative, then we will need an
1370 adjustment for the high order 16 bits. */
1372 val = (val >> 16) & 0xffff;
1374 insn &= ~ (bfd_vma) 0xffff;
1376 bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
1383 mips_hi16_list = NULL;
1386 /* Now do the LO16 reloc in the usual way. */
1387 return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1388 input_section, output_bfd, error_message);
1391 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1392 table used for PIC code. If the symbol is an external symbol, the
1393 instruction is modified to contain the offset of the appropriate
1394 entry in the global offset table. If the symbol is a section
1395 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1396 addends are combined to form the real addend against the section
1397 symbol; the GOT16 is modified to contain the offset of an entry in
1398 the global offset table, and the LO16 is modified to offset it
1399 appropriately. Thus an offset larger than 16 bits requires a
1400 modified value in the global offset table.
1402 This implementation suffices for the assembler, but the linker does
1403 not yet know how to create global offset tables. */
1405 static bfd_reloc_status_type
1406 mips_elf_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1407 output_bfd, error_message)
1409 arelent *reloc_entry;
1412 asection *input_section;
1414 char **error_message;
1416 /* If we're relocating, and this is a local symbol, we can handle it
1418 if (output_bfd != (bfd *) NULL
1419 && (symbol->flags & BSF_SECTION_SYM) != 0)
1420 return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
1421 input_section, output_bfd, error_message);
1423 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1424 return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1425 input_section, output_bfd, error_message);
1428 /* Set the GP value for OUTPUT_BFD. Returns false if this is a
1429 dangerous relocation. */
1432 mips_elf_assign_gp (output_bfd, pgp)
1440 /* If we've already figured out what GP will be, just return it. */
1441 *pgp = _bfd_get_gp_value (output_bfd);
1445 count = bfd_get_symcount (output_bfd);
1446 sym = bfd_get_outsymbols (output_bfd);
1448 /* The linker script will have created a symbol named `_gp' with the
1449 appropriate value. */
1450 if (sym == (asymbol **) NULL)
1454 for (i = 0; i < count; i++, sym++)
1456 register const char *name;
1458 name = bfd_asymbol_name (*sym);
1459 if (*name == '_' && strcmp (name, "_gp") == 0)
1461 *pgp = bfd_asymbol_value (*sym);
1462 _bfd_set_gp_value (output_bfd, *pgp);
1470 /* Only get the error once. */
1472 _bfd_set_gp_value (output_bfd, *pgp);
1479 /* We have to figure out the gp value, so that we can adjust the
1480 symbol value correctly. We look up the symbol _gp in the output
1481 BFD. If we can't find it, we're stuck. We cache it in the ELF
1482 target data. We don't need to adjust the symbol value for an
1483 external symbol if we are producing relocateable output. */
1485 static bfd_reloc_status_type
1486 mips_elf_final_gp (output_bfd, symbol, relocateable, error_message, pgp)
1489 boolean relocateable;
1490 char **error_message;
1493 if (bfd_is_und_section (symbol->section)
1497 return bfd_reloc_undefined;
1500 *pgp = _bfd_get_gp_value (output_bfd);
1503 || (symbol->flags & BSF_SECTION_SYM) != 0))
1507 /* Make up a value. */
1508 *pgp = symbol->section->output_section->vma + 0x4000;
1509 _bfd_set_gp_value (output_bfd, *pgp);
1511 else if (!mips_elf_assign_gp (output_bfd, pgp))
1514 (char *) _("GP relative relocation when _gp not defined");
1515 return bfd_reloc_dangerous;
1519 return bfd_reloc_ok;
1522 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1523 become the offset from the gp register. */
1525 static bfd_reloc_status_type
1526 mips_elf_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
1527 output_bfd, error_message)
1528 bfd *abfd ATTRIBUTE_UNUSED;
1529 arelent *reloc_entry;
1531 PTR data ATTRIBUTE_UNUSED;
1532 asection *input_section;
1534 char **error_message ATTRIBUTE_UNUSED;
1536 boolean relocateable;
1537 bfd_reloc_status_type ret;
1540 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1542 if (output_bfd != (bfd *) NULL)
1543 relocateable = true;
1546 relocateable = false;
1547 output_bfd = symbol->section->output_section->owner;
1550 ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
1552 if (ret != bfd_reloc_ok)
1555 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1556 input_section, relocateable,
1560 /* Do a R_MIPS_LITERAL relocation. */
1562 static bfd_reloc_status_type
1563 mips_elf_literal_reloc (abfd, reloc_entry, symbol, data, input_section,
1564 output_bfd, error_message)
1566 arelent *reloc_entry;
1569 asection *input_section;
1571 char **error_message;
1573 boolean relocateable;
1574 bfd_reloc_status_type ret;
1577 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1579 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1580 if (output_bfd != (bfd *) NULL)
1581 relocateable = true;
1584 relocateable = false;
1585 output_bfd = symbol->section->output_section->owner;
1588 ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
1590 if (ret != bfd_reloc_ok)
1593 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1594 input_section, relocateable,
1598 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1599 become the offset from the gp register. */
1601 static bfd_reloc_status_type
1602 mips_elf_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section,
1603 output_bfd, error_message)
1605 arelent *reloc_entry;
1608 asection *input_section;
1610 char **error_message;
1612 boolean relocateable;
1613 bfd_reloc_status_type ret;
1616 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1618 /* R_MIPS_GPREL32 relocations are defined for local symbols only.
1619 We will only have an addend if this is a newly created reloc,
1620 not read from an ELF file. */
1621 if (output_bfd != (bfd *) NULL
1622 && (symbol->flags & BSF_SECTION_SYM) == 0
1623 && reloc_entry->addend == 0)
1625 *error_message = (char *)
1626 _("32bits gp relative relocation occurs for an external symbol");
1627 return bfd_reloc_outofrange;
1630 if (output_bfd != (bfd *) NULL)
1632 relocateable = true;
1633 gp = _bfd_get_gp_value (output_bfd);
1637 relocateable = false;
1638 output_bfd = symbol->section->output_section->owner;
1640 ret = mips_elf_final_gp (output_bfd, symbol, relocateable,
1641 error_message, &gp);
1642 if (ret != bfd_reloc_ok)
1646 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1647 relocateable, data, gp);
1650 static bfd_reloc_status_type
1651 gprel32_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data,
1655 arelent *reloc_entry;
1656 asection *input_section;
1657 boolean relocateable;
1664 if (bfd_is_com_section (symbol->section))
1667 relocation = symbol->value;
1669 relocation += symbol->section->output_section->vma;
1670 relocation += symbol->section->output_offset;
1672 if (reloc_entry->address > input_section->_cooked_size)
1673 return bfd_reloc_outofrange;
1675 if (reloc_entry->howto->src_mask == 0)
1678 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1680 /* Set val to the offset into the section or symbol. */
1681 val += reloc_entry->addend;
1683 /* Adjust val for the final section location and GP value. If we
1684 are producing relocateable output, we don't want to do this for
1685 an external symbol. */
1687 || (symbol->flags & BSF_SECTION_SYM) != 0)
1688 val += relocation - gp;
1690 bfd_put_32 (abfd, (bfd_vma) val, (bfd_byte *) data + reloc_entry->address);
1693 reloc_entry->address += input_section->output_offset;
1695 return bfd_reloc_ok;
1698 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1699 the rest is at bits 6-10. The bitpos already got right by the howto. */
1701 static bfd_reloc_status_type
1702 mips_elf_shift6_reloc (abfd, reloc_entry, symbol, data, input_section,
1703 output_bfd, error_message)
1704 bfd *abfd ATTRIBUTE_UNUSED;
1705 arelent *reloc_entry;
1707 PTR data ATTRIBUTE_UNUSED;
1708 asection *input_section;
1710 char **error_message ATTRIBUTE_UNUSED;
1712 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1714 reloc_entry->addend = (reloc_entry->addend & 0x00007c0)
1715 | (reloc_entry->addend & 0x00000800) >> 9;
1717 SET_RELOC_ADDEND (reloc_entry)
1719 return bfd_reloc_continue;
1722 /* Handle a mips16 jump. */
1724 static bfd_reloc_status_type
1725 mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
1726 output_bfd, error_message)
1727 bfd *abfd ATTRIBUTE_UNUSED;
1728 arelent *reloc_entry;
1730 PTR data ATTRIBUTE_UNUSED;
1731 asection *input_section;
1733 char **error_message ATTRIBUTE_UNUSED;
1735 static boolean warned = false;
1737 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1741 (*_bfd_error_handler)
1742 (_("Linking mips16 objects into %s format is not supported"),
1743 bfd_get_target (input_section->output_section->owner));
1746 return bfd_reloc_undefined;
1749 /* Handle a mips16 GP relative reloc. */
1751 static bfd_reloc_status_type
1752 mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
1753 output_bfd, error_message)
1755 arelent *reloc_entry;
1758 asection *input_section;
1760 char **error_message;
1762 boolean relocateable;
1763 bfd_reloc_status_type ret;
1765 unsigned short extend, insn;
1766 unsigned long final;
1768 GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
1770 if (output_bfd != NULL)
1771 relocateable = true;
1774 relocateable = false;
1775 output_bfd = symbol->section->output_section->owner;
1778 ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
1780 if (ret != bfd_reloc_ok)
1783 if (reloc_entry->address > input_section->_cooked_size)
1784 return bfd_reloc_outofrange;
1786 /* Pick up the mips16 extend instruction and the real instruction. */
1787 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1788 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1790 /* Stuff the current addend back as a 32 bit value, do the usual
1791 relocation, and then clean up. */
1793 (bfd_vma) (((extend & 0x1f) << 11)
1796 (bfd_byte *) data + reloc_entry->address);
1798 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1799 input_section, relocateable, data, gp);
1801 final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1803 (bfd_vma) ((extend & 0xf800)
1804 | ((final >> 11) & 0x1f)
1806 (bfd_byte *) data + reloc_entry->address);
1808 (bfd_vma) ((insn & 0xffe0)
1810 (bfd_byte *) data + reloc_entry->address + 2);
1815 #undef GET_RELOC_ADDEND
1816 #undef SET_RELOC_ADDEND
1818 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1820 struct elf_reloc_map {
1821 bfd_reloc_code_real_type bfd_val;
1822 enum elf_mips_reloc_type elf_val;
1825 static const struct elf_reloc_map mips_reloc_map[] =
1827 { BFD_RELOC_NONE, R_MIPS_NONE },
1828 { BFD_RELOC_16, R_MIPS_16 },
1829 { BFD_RELOC_32, R_MIPS_32 },
1830 /* There is no BFD reloc for R_MIPS_REL32. */
1831 { BFD_RELOC_CTOR, R_MIPS_32 },
1832 { BFD_RELOC_64, R_MIPS_64 },
1833 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1834 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1835 { BFD_RELOC_LO16, R_MIPS_LO16 },
1836 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1837 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1838 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1839 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1840 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1841 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1842 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1843 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1844 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1845 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1846 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1847 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1848 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1849 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1850 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1851 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1852 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1853 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1854 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1855 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1856 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1857 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1858 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1859 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1860 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1861 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1864 /* Given a BFD reloc type, return a howto structure. */
1866 static reloc_howto_type *
1867 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
1868 bfd *abfd ATTRIBUTE_UNUSED;
1869 bfd_reloc_code_real_type code;
1872 /* FIXME: We default to RELA here instead of choosing the right
1873 relocation variant. */
1874 reloc_howto_type *howto_table = elf_mips_howto_table_rela;
1876 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1879 if (mips_reloc_map[i].bfd_val == code)
1880 return &howto_table[(int) mips_reloc_map[i].elf_val];
1885 case BFD_RELOC_MIPS16_JMP:
1886 return &elf_mips16_jump_howto;
1887 case BFD_RELOC_MIPS16_GPREL:
1888 return &elf_mips16_gprel_howto;
1889 case BFD_RELOC_VTABLE_INHERIT:
1890 return &elf_mips_gnu_vtinherit_howto;
1891 case BFD_RELOC_VTABLE_ENTRY:
1892 return &elf_mips_gnu_vtentry_howto;
1894 bfd_set_error (bfd_error_bad_value);
1899 /* Given a MIPS Elf32_Internal_Rel, fill in an arelent structure. */
1901 static reloc_howto_type *
1902 mips_elf_n32_rtype_to_howto (r_type, rela_p)
1903 unsigned int r_type;
1909 return &elf_mips16_jump_howto;
1910 case R_MIPS16_GPREL:
1911 return &elf_mips16_gprel_howto;
1912 case R_MIPS_GNU_VTINHERIT:
1913 return &elf_mips_gnu_vtinherit_howto;
1914 case R_MIPS_GNU_VTENTRY:
1915 return &elf_mips_gnu_vtentry_howto;
1917 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1919 return &elf_mips_howto_table_rela[r_type];
1921 return &elf_mips_howto_table_rel[r_type];
1926 /* Given a MIPS Elf32_Internal_Rel, fill in an arelent structure. */
1929 mips_info_to_howto_rel (abfd, cache_ptr, dst)
1932 Elf32_Internal_Rel *dst;
1934 unsigned int r_type;
1936 r_type = ELF32_R_TYPE (dst->r_info);
1937 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, false);
1939 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1940 value for the object file. We get the addend now, rather than
1941 when we do the relocation, because the symbol manipulations done
1942 by the linker may cause us to lose track of the input BFD. */
1943 if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1944 && (r_type == (unsigned int) R_MIPS_GPREL16
1945 || r_type == (unsigned int) R_MIPS_LITERAL))
1946 cache_ptr->addend = elf_gp (abfd);
1949 /* Given a MIPS Elf32_Internal_Rela, fill in an arelent structure. */
1952 mips_info_to_howto_rela (abfd, cache_ptr, dst)
1953 bfd *abfd ATTRIBUTE_UNUSED;
1955 Elf32_Internal_Rela *dst;
1957 unsigned int r_type;
1959 r_type = ELF32_R_TYPE (dst->r_info);
1960 cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, true);
1961 cache_ptr->addend = dst->r_addend;
1964 /* Determine whether a symbol is global for the purposes of splitting
1965 the symbol table into global symbols and local symbols. At least
1966 on Irix 5, this split must be between section symbols and all other
1967 symbols. On most ELF targets the split is between static symbols
1968 and externally visible symbols. */
1971 mips_elf_sym_is_global (abfd, sym)
1972 bfd *abfd ATTRIBUTE_UNUSED;
1975 if (SGI_COMPAT (abfd))
1976 return (sym->flags & BSF_SECTION_SYM) == 0;
1978 return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1979 || bfd_is_und_section (bfd_get_section (sym))
1980 || bfd_is_com_section (bfd_get_section (sym)));
1983 /* Set the right machine number for a MIPS ELF file. */
1986 mips_elf_n32_object_p (abfd)
1991 /* Irix 5 and 6 are broken. Object file symbol tables are not always
1992 sorted correctly such that local symbols precede global symbols,
1993 and the sh_info field in the symbol table is not always right. */
1994 if (SGI_COMPAT (abfd))
1995 elf_bad_symtab (abfd) = true;
1997 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
1998 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2000 if (! ABI_N32_P(abfd))
2006 /* Support for core dump NOTE sections. */
2008 elf32_mips_grok_prstatus (abfd, note)
2010 Elf_Internal_Note *note;
2013 unsigned int raw_size;
2015 switch (note->descsz)
2020 case 256: /* Linux/MIPS */
2022 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2025 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
2034 /* Make a ".reg/999" section. */
2035 return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
2036 note->descpos + offset);
2040 elf32_mips_grok_psinfo (abfd, note)
2042 Elf_Internal_Note *note;
2044 switch (note->descsz)
2049 case 128: /* Linux/MIPS elf_prpsinfo */
2050 elf_tdata (abfd)->core_program
2051 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
2052 elf_tdata (abfd)->core_command
2053 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
2056 /* Note that for some reason, a spurious space is tacked
2057 onto the end of the args in some (at least one anyway)
2058 implementations, so strip it off if it exists. */
2061 char *command = elf_tdata (abfd)->core_command;
2062 int n = strlen (command);
2064 if (0 < n && command[n - 1] == ' ')
2065 command[n - 1] = '\0';
2071 /* Depending on the target vector we generate some version of Irix
2072 executables or "normal" MIPS ELF ABI executables. */
2073 static irix_compat_t
2074 elf_n32_mips_irix_compat (abfd)
2077 if ((abfd->xvec == &bfd_elf32_nbigmips_vec)
2078 || (abfd->xvec == &bfd_elf32_nlittlemips_vec))
2084 /* ECOFF swapping routines. These are used when dealing with the
2085 .mdebug section, which is in the ECOFF debugging format. */
2086 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
2087 /* Symbol table magic number. */
2089 /* Alignment of debugging information. E.g., 4. */
2091 /* Sizes of external symbolic information. */
2092 sizeof (struct hdr_ext),
2093 sizeof (struct dnr_ext),
2094 sizeof (struct pdr_ext),
2095 sizeof (struct sym_ext),
2096 sizeof (struct opt_ext),
2097 sizeof (struct fdr_ext),
2098 sizeof (struct rfd_ext),
2099 sizeof (struct ext_ext),
2100 /* Functions to swap in external symbolic data. */
2109 _bfd_ecoff_swap_tir_in,
2110 _bfd_ecoff_swap_rndx_in,
2111 /* Functions to swap out external symbolic data. */
2120 _bfd_ecoff_swap_tir_out,
2121 _bfd_ecoff_swap_rndx_out,
2122 /* Function to read in symbolic data. */
2123 _bfd_mips_elf_read_ecoff_info
2126 #define ELF_ARCH bfd_arch_mips
2127 #define ELF_MACHINE_CODE EM_MIPS
2129 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2130 a value of 0x1000, and we are compatible.
2131 FIXME: How does this affect NewABI? */
2132 #define ELF_MAXPAGESIZE 0x1000
2134 #define elf_backend_collect true
2135 #define elf_backend_type_change_ok true
2136 #define elf_backend_can_gc_sections true
2137 #define elf_info_to_howto mips_info_to_howto_rela
2138 #define elf_info_to_howto_rel mips_info_to_howto_rel
2139 #define elf_backend_sym_is_global mips_elf_sym_is_global
2140 #define elf_backend_object_p mips_elf_n32_object_p
2141 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2142 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2143 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2144 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2145 #define elf_backend_section_from_bfd_section \
2146 _bfd_mips_elf_section_from_bfd_section
2147 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2148 #define elf_backend_link_output_symbol_hook \
2149 _bfd_mips_elf_link_output_symbol_hook
2150 #define elf_backend_create_dynamic_sections \
2151 _bfd_mips_elf_create_dynamic_sections
2152 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2153 #define elf_backend_adjust_dynamic_symbol \
2154 _bfd_mips_elf_adjust_dynamic_symbol
2155 #define elf_backend_always_size_sections \
2156 _bfd_mips_elf_always_size_sections
2157 #define elf_backend_size_dynamic_sections \
2158 _bfd_mips_elf_size_dynamic_sections
2159 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2160 #define elf_backend_finish_dynamic_symbol \
2161 _bfd_mips_elf_finish_dynamic_symbol
2162 #define elf_backend_finish_dynamic_sections \
2163 _bfd_mips_elf_finish_dynamic_sections
2164 #define elf_backend_final_write_processing \
2165 _bfd_mips_elf_final_write_processing
2166 #define elf_backend_additional_program_headers \
2167 _bfd_mips_elf_additional_program_headers
2168 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2169 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2170 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2171 #define elf_backend_copy_indirect_symbol \
2172 _bfd_mips_elf_copy_indirect_symbol
2173 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2174 #define elf_backend_grok_prstatus elf32_mips_grok_prstatus
2175 #define elf_backend_grok_psinfo elf32_mips_grok_psinfo
2176 #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
2178 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2179 #define elf_backend_plt_header_size 0
2181 /* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
2182 work better/work only in RELA, so we default to this. */
2183 #define elf_backend_may_use_rel_p 1
2184 #define elf_backend_may_use_rela_p 1
2185 #define elf_backend_default_use_rela_p 1
2186 #define elf_backend_sign_extend_vma true
2188 #define elf_backend_discard_info _bfd_mips_elf_discard_info
2189 #define elf_backend_ignore_discarded_relocs \
2190 _bfd_mips_elf_ignore_discarded_relocs
2191 #define elf_backend_write_section _bfd_mips_elf_write_section
2192 #define elf_backend_mips_irix_compat elf_n32_mips_irix_compat
2193 #define elf_backend_mips_rtype_to_howto mips_elf_n32_rtype_to_howto
2194 #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
2195 #define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
2196 #define bfd_elf32_bfd_get_relocated_section_contents \
2197 _bfd_elf_mips_get_relocated_section_contents
2198 #define bfd_elf32_bfd_link_hash_table_create \
2199 _bfd_mips_elf_link_hash_table_create
2200 #define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
2201 #define bfd_elf32_bfd_merge_private_bfd_data \
2202 _bfd_mips_elf_merge_private_bfd_data
2203 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2204 #define bfd_elf32_bfd_print_private_bfd_data \
2205 _bfd_mips_elf_print_private_bfd_data
2207 /* Support for SGI-ish mips targets using n32 ABI. */
2209 #define TARGET_LITTLE_SYM bfd_elf32_nlittlemips_vec
2210 #define TARGET_LITTLE_NAME "elf32-nlittlemips"
2211 #define TARGET_BIG_SYM bfd_elf32_nbigmips_vec
2212 #define TARGET_BIG_NAME "elf32-nbigmips"
2214 #include "elf32-target.h"
2216 /* Support for traditional mips targets using n32 ABI. */
2217 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2219 #undef TARGET_LITTLE_SYM
2220 #undef TARGET_LITTLE_NAME
2221 #undef TARGET_BIG_SYM
2222 #undef TARGET_BIG_NAME
2224 #define TARGET_LITTLE_SYM bfd_elf32_ntradlittlemips_vec
2225 #define TARGET_LITTLE_NAME "elf32-ntradlittlemips"
2226 #define TARGET_BIG_SYM bfd_elf32_ntradbigmips_vec
2227 #define TARGET_BIG_NAME "elf32-ntradbigmips"
2229 /* Include the target file again for this target. */
2230 #include "elf32-target.h"