1 /* MIPS-specific support for 32-bit ELF
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 2003, 2004, 2005 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 gprel32_with_gp
51 (bfd
*, asymbol
*, arelent
*, asection
*, bfd_boolean
, void *, bfd_vma
);
52 static bfd_reloc_status_type mips_elf_gprel32_reloc
53 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
54 static bfd_reloc_status_type mips32_64bit_reloc
55 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
56 static reloc_howto_type
*bfd_elf32_bfd_reloc_type_lookup
57 (bfd
*, bfd_reloc_code_real_type
);
58 static reloc_howto_type
*mips_elf32_rtype_to_howto
59 (unsigned int, bfd_boolean
);
60 static void mips_info_to_howto_rel
61 (bfd
*, arelent
*, Elf_Internal_Rela
*);
62 static void mips_info_to_howto_rela
63 (bfd
*, arelent
*, Elf_Internal_Rela
*);
64 static bfd_boolean mips_elf_sym_is_global
66 static bfd_boolean mips_elf32_object_p
68 static bfd_boolean mips_elf_is_local_label_name
69 (bfd
*, const char *);
70 static bfd_reloc_status_type mips16_jump_reloc
71 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
72 static bfd_reloc_status_type mips16_gprel_reloc
73 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
74 static bfd_reloc_status_type mips_elf_final_gp
75 (bfd
*, asymbol
*, bfd_boolean
, char **, bfd_vma
*);
76 static bfd_boolean mips_elf_assign_gp
78 static bfd_boolean elf32_mips_grok_prstatus
79 (bfd
*, Elf_Internal_Note
*);
80 static bfd_boolean elf32_mips_grok_psinfo
81 (bfd
*, Elf_Internal_Note
*);
82 static irix_compat_t elf32_mips_irix_compat
85 extern const bfd_target bfd_elf32_bigmips_vec
;
86 extern const bfd_target bfd_elf32_littlemips_vec
;
88 /* Nonzero if ABFD is using the N32 ABI. */
89 #define ABI_N32_P(abfd) \
90 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
92 /* Whether we are trying to be compatible with IRIX at all. */
93 #define SGI_COMPAT(abfd) \
94 (elf32_mips_irix_compat (abfd) != ict_none)
96 /* The number of local .got entries we reserve. */
97 #define MIPS_RESERVED_GOTNO (2)
99 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
100 from smaller values. Start with zero, widen, *then* decrement. */
101 #define MINUS_ONE (((bfd_vma)0) - 1)
103 /* The relocation table used for SHT_REL sections. */
105 static reloc_howto_type elf_mips_howto_table_rel
[] =
108 HOWTO (R_MIPS_NONE
, /* type */
110 0, /* size (0 = byte, 1 = short, 2 = long) */
112 FALSE
, /* pc_relative */
114 complain_overflow_dont
, /* complain_on_overflow */
115 _bfd_mips_elf_generic_reloc
, /* special_function */
116 "R_MIPS_NONE", /* name */
117 FALSE
, /* partial_inplace */
120 FALSE
), /* pcrel_offset */
122 /* 16 bit relocation. */
123 HOWTO (R_MIPS_16
, /* type */
125 2, /* size (0 = byte, 1 = short, 2 = long) */
127 FALSE
, /* pc_relative */
129 complain_overflow_signed
, /* complain_on_overflow */
130 _bfd_mips_elf_generic_reloc
, /* special_function */
131 "R_MIPS_16", /* name */
132 TRUE
, /* partial_inplace */
133 0x0000ffff, /* src_mask */
134 0x0000ffff, /* dst_mask */
135 FALSE
), /* pcrel_offset */
137 /* 32 bit relocation. */
138 HOWTO (R_MIPS_32
, /* type */
140 2, /* size (0 = byte, 1 = short, 2 = long) */
142 FALSE
, /* pc_relative */
144 complain_overflow_dont
, /* complain_on_overflow */
145 _bfd_mips_elf_generic_reloc
, /* special_function */
146 "R_MIPS_32", /* name */
147 TRUE
, /* partial_inplace */
148 0xffffffff, /* src_mask */
149 0xffffffff, /* dst_mask */
150 FALSE
), /* pcrel_offset */
152 /* 32 bit symbol relative relocation. */
153 HOWTO (R_MIPS_REL32
, /* type */
155 2, /* size (0 = byte, 1 = short, 2 = long) */
157 FALSE
, /* pc_relative */
159 complain_overflow_dont
, /* complain_on_overflow */
160 _bfd_mips_elf_generic_reloc
, /* special_function */
161 "R_MIPS_REL32", /* name */
162 TRUE
, /* partial_inplace */
163 0xffffffff, /* src_mask */
164 0xffffffff, /* dst_mask */
165 FALSE
), /* pcrel_offset */
167 /* 26 bit jump address. */
168 HOWTO (R_MIPS_26
, /* type */
170 2, /* size (0 = byte, 1 = short, 2 = long) */
172 FALSE
, /* pc_relative */
174 complain_overflow_dont
, /* complain_on_overflow */
175 /* This needs complex overflow
176 detection, because the upper four
177 bits must match the PC + 4. */
178 _bfd_mips_elf_generic_reloc
, /* special_function */
179 "R_MIPS_26", /* name */
180 TRUE
, /* partial_inplace */
181 0x03ffffff, /* src_mask */
182 0x03ffffff, /* dst_mask */
183 FALSE
), /* pcrel_offset */
185 /* High 16 bits of symbol value. */
186 HOWTO (R_MIPS_HI16
, /* type */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
190 FALSE
, /* pc_relative */
192 complain_overflow_dont
, /* complain_on_overflow */
193 _bfd_mips_elf_hi16_reloc
, /* special_function */
194 "R_MIPS_HI16", /* name */
195 TRUE
, /* partial_inplace */
196 0x0000ffff, /* src_mask */
197 0x0000ffff, /* dst_mask */
198 FALSE
), /* pcrel_offset */
200 /* Low 16 bits of symbol value. */
201 HOWTO (R_MIPS_LO16
, /* type */
203 2, /* size (0 = byte, 1 = short, 2 = long) */
205 FALSE
, /* pc_relative */
207 complain_overflow_dont
, /* complain_on_overflow */
208 _bfd_mips_elf_lo16_reloc
, /* special_function */
209 "R_MIPS_LO16", /* name */
210 TRUE
, /* partial_inplace */
211 0x0000ffff, /* src_mask */
212 0x0000ffff, /* dst_mask */
213 FALSE
), /* pcrel_offset */
215 /* GP relative reference. */
216 HOWTO (R_MIPS_GPREL16
, /* type */
218 2, /* size (0 = byte, 1 = short, 2 = long) */
220 FALSE
, /* pc_relative */
222 complain_overflow_signed
, /* complain_on_overflow */
223 _bfd_mips_elf32_gprel16_reloc
, /* special_function */
224 "R_MIPS_GPREL16", /* name */
225 TRUE
, /* partial_inplace */
226 0x0000ffff, /* src_mask */
227 0x0000ffff, /* dst_mask */
228 FALSE
), /* pcrel_offset */
230 /* Reference to literal section. */
231 HOWTO (R_MIPS_LITERAL
, /* type */
233 2, /* size (0 = byte, 1 = short, 2 = long) */
235 FALSE
, /* pc_relative */
237 complain_overflow_signed
, /* complain_on_overflow */
238 _bfd_mips_elf32_gprel16_reloc
, /* special_function */
239 "R_MIPS_LITERAL", /* name */
240 TRUE
, /* partial_inplace */
241 0x0000ffff, /* src_mask */
242 0x0000ffff, /* dst_mask */
243 FALSE
), /* pcrel_offset */
245 /* Reference to global offset table. */
246 HOWTO (R_MIPS_GOT16
, /* type */
248 2, /* size (0 = byte, 1 = short, 2 = long) */
250 FALSE
, /* pc_relative */
252 complain_overflow_signed
, /* complain_on_overflow */
253 _bfd_mips_elf_got16_reloc
, /* special_function */
254 "R_MIPS_GOT16", /* name */
255 TRUE
, /* partial_inplace */
256 0x0000ffff, /* src_mask */
257 0x0000ffff, /* dst_mask */
258 FALSE
), /* pcrel_offset */
260 /* 16 bit PC relative reference. Note that the ABI document has a typo
261 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
262 We do the right thing here. */
263 HOWTO (R_MIPS_PC16
, /* type */
265 2, /* size (0 = byte, 1 = short, 2 = long) */
267 TRUE
, /* pc_relative */
269 complain_overflow_signed
, /* complain_on_overflow */
270 _bfd_mips_elf_generic_reloc
, /* special_function */
271 "R_MIPS_PC16", /* name */
272 TRUE
, /* partial_inplace */
273 0x0000ffff, /* src_mask */
274 0x0000ffff, /* dst_mask */
275 TRUE
), /* pcrel_offset */
277 /* 16 bit call through global offset table. */
278 HOWTO (R_MIPS_CALL16
, /* type */
280 2, /* size (0 = byte, 1 = short, 2 = long) */
282 FALSE
, /* pc_relative */
284 complain_overflow_signed
, /* complain_on_overflow */
285 _bfd_mips_elf_generic_reloc
, /* special_function */
286 "R_MIPS_CALL16", /* name */
287 TRUE
, /* partial_inplace */
288 0x0000ffff, /* src_mask */
289 0x0000ffff, /* dst_mask */
290 FALSE
), /* pcrel_offset */
292 /* 32 bit GP relative reference. */
293 HOWTO (R_MIPS_GPREL32
, /* type */
295 2, /* size (0 = byte, 1 = short, 2 = long) */
297 FALSE
, /* pc_relative */
299 complain_overflow_dont
, /* complain_on_overflow */
300 mips_elf_gprel32_reloc
, /* special_function */
301 "R_MIPS_GPREL32", /* name */
302 TRUE
, /* partial_inplace */
303 0xffffffff, /* src_mask */
304 0xffffffff, /* dst_mask */
305 FALSE
), /* pcrel_offset */
307 /* The remaining relocs are defined on Irix 5, although they are
308 not defined by the ABI. */
313 /* A 5 bit shift field. */
314 HOWTO (R_MIPS_SHIFT5
, /* type */
316 2, /* size (0 = byte, 1 = short, 2 = long) */
318 FALSE
, /* pc_relative */
320 complain_overflow_bitfield
, /* complain_on_overflow */
321 _bfd_mips_elf_generic_reloc
, /* special_function */
322 "R_MIPS_SHIFT5", /* name */
323 TRUE
, /* partial_inplace */
324 0x000007c0, /* src_mask */
325 0x000007c0, /* dst_mask */
326 FALSE
), /* pcrel_offset */
328 /* A 6 bit shift field. */
329 /* FIXME: This is not handled correctly; a special function is
330 needed to put the most significant bit in the right place. */
331 HOWTO (R_MIPS_SHIFT6
, /* type */
333 2, /* size (0 = byte, 1 = short, 2 = long) */
335 FALSE
, /* pc_relative */
337 complain_overflow_bitfield
, /* complain_on_overflow */
338 _bfd_mips_elf_generic_reloc
, /* special_function */
339 "R_MIPS_SHIFT6", /* name */
340 TRUE
, /* partial_inplace */
341 0x000007c4, /* src_mask */
342 0x000007c4, /* dst_mask */
343 FALSE
), /* pcrel_offset */
345 /* A 64 bit relocation. */
346 HOWTO (R_MIPS_64
, /* type */
348 4, /* size (0 = byte, 1 = short, 2 = long) */
350 FALSE
, /* pc_relative */
352 complain_overflow_dont
, /* complain_on_overflow */
353 mips32_64bit_reloc
, /* special_function */
354 "R_MIPS_64", /* name */
355 TRUE
, /* partial_inplace */
356 MINUS_ONE
, /* src_mask */
357 MINUS_ONE
, /* dst_mask */
358 FALSE
), /* pcrel_offset */
360 /* Displacement in the global offset table. */
361 HOWTO (R_MIPS_GOT_DISP
, /* type */
363 2, /* size (0 = byte, 1 = short, 2 = long) */
365 FALSE
, /* pc_relative */
367 complain_overflow_signed
, /* complain_on_overflow */
368 _bfd_mips_elf_generic_reloc
, /* special_function */
369 "R_MIPS_GOT_DISP", /* name */
370 TRUE
, /* partial_inplace */
371 0x0000ffff, /* src_mask */
372 0x0000ffff, /* dst_mask */
373 FALSE
), /* pcrel_offset */
375 /* Displacement to page pointer in the global offset table. */
376 HOWTO (R_MIPS_GOT_PAGE
, /* type */
378 2, /* size (0 = byte, 1 = short, 2 = long) */
380 FALSE
, /* pc_relative */
382 complain_overflow_signed
, /* complain_on_overflow */
383 _bfd_mips_elf_generic_reloc
, /* special_function */
384 "R_MIPS_GOT_PAGE", /* name */
385 TRUE
, /* partial_inplace */
386 0x0000ffff, /* src_mask */
387 0x0000ffff, /* dst_mask */
388 FALSE
), /* pcrel_offset */
390 /* Offset from page pointer in the global offset table. */
391 HOWTO (R_MIPS_GOT_OFST
, /* type */
393 2, /* size (0 = byte, 1 = short, 2 = long) */
395 FALSE
, /* pc_relative */
397 complain_overflow_signed
, /* complain_on_overflow */
398 _bfd_mips_elf_generic_reloc
, /* special_function */
399 "R_MIPS_GOT_OFST", /* name */
400 TRUE
, /* partial_inplace */
401 0x0000ffff, /* src_mask */
402 0x0000ffff, /* dst_mask */
403 FALSE
), /* pcrel_offset */
405 /* High 16 bits of displacement in global offset table. */
406 HOWTO (R_MIPS_GOT_HI16
, /* type */
408 2, /* size (0 = byte, 1 = short, 2 = long) */
410 FALSE
, /* pc_relative */
412 complain_overflow_dont
, /* complain_on_overflow */
413 _bfd_mips_elf_generic_reloc
, /* special_function */
414 "R_MIPS_GOT_HI16", /* name */
415 TRUE
, /* partial_inplace */
416 0x0000ffff, /* src_mask */
417 0x0000ffff, /* dst_mask */
418 FALSE
), /* pcrel_offset */
420 /* Low 16 bits of displacement in global offset table. */
421 HOWTO (R_MIPS_GOT_LO16
, /* type */
423 2, /* size (0 = byte, 1 = short, 2 = long) */
425 FALSE
, /* pc_relative */
427 complain_overflow_dont
, /* complain_on_overflow */
428 _bfd_mips_elf_generic_reloc
, /* special_function */
429 "R_MIPS_GOT_LO16", /* name */
430 TRUE
, /* partial_inplace */
431 0x0000ffff, /* src_mask */
432 0x0000ffff, /* dst_mask */
433 FALSE
), /* pcrel_offset */
435 /* 64 bit subtraction. Used in the N32 ABI. */
436 HOWTO (R_MIPS_SUB
, /* type */
438 4, /* size (0 = byte, 1 = short, 2 = long) */
440 FALSE
, /* pc_relative */
442 complain_overflow_dont
, /* complain_on_overflow */
443 _bfd_mips_elf_generic_reloc
, /* special_function */
444 "R_MIPS_SUB", /* name */
445 TRUE
, /* partial_inplace */
446 MINUS_ONE
, /* src_mask */
447 MINUS_ONE
, /* dst_mask */
448 FALSE
), /* pcrel_offset */
450 /* Used to cause the linker to insert and delete instructions? */
451 EMPTY_HOWTO (R_MIPS_INSERT_A
),
452 EMPTY_HOWTO (R_MIPS_INSERT_B
),
453 EMPTY_HOWTO (R_MIPS_DELETE
),
455 /* Get the higher value of a 64 bit addend. */
456 HOWTO (R_MIPS_HIGHER
, /* type */
458 2, /* size (0 = byte, 1 = short, 2 = long) */
460 FALSE
, /* pc_relative */
462 complain_overflow_dont
, /* complain_on_overflow */
463 _bfd_mips_elf_generic_reloc
, /* special_function */
464 "R_MIPS_HIGHER", /* name */
465 TRUE
, /* partial_inplace */
466 0x0000ffff, /* src_mask */
467 0x0000ffff, /* dst_mask */
468 FALSE
), /* pcrel_offset */
470 /* Get the highest value of a 64 bit addend. */
471 HOWTO (R_MIPS_HIGHEST
, /* type */
473 2, /* size (0 = byte, 1 = short, 2 = long) */
475 FALSE
, /* pc_relative */
477 complain_overflow_dont
, /* complain_on_overflow */
478 _bfd_mips_elf_generic_reloc
, /* special_function */
479 "R_MIPS_HIGHEST", /* name */
480 TRUE
, /* partial_inplace */
481 0x0000ffff, /* src_mask */
482 0x0000ffff, /* dst_mask */
483 FALSE
), /* pcrel_offset */
485 /* High 16 bits of displacement in global offset table. */
486 HOWTO (R_MIPS_CALL_HI16
, /* type */
488 2, /* size (0 = byte, 1 = short, 2 = long) */
490 FALSE
, /* pc_relative */
492 complain_overflow_dont
, /* complain_on_overflow */
493 _bfd_mips_elf_generic_reloc
, /* special_function */
494 "R_MIPS_CALL_HI16", /* name */
495 TRUE
, /* partial_inplace */
496 0x0000ffff, /* src_mask */
497 0x0000ffff, /* dst_mask */
498 FALSE
), /* pcrel_offset */
500 /* Low 16 bits of displacement in global offset table. */
501 HOWTO (R_MIPS_CALL_LO16
, /* type */
503 2, /* size (0 = byte, 1 = short, 2 = long) */
505 FALSE
, /* pc_relative */
507 complain_overflow_dont
, /* complain_on_overflow */
508 _bfd_mips_elf_generic_reloc
, /* special_function */
509 "R_MIPS_CALL_LO16", /* name */
510 TRUE
, /* partial_inplace */
511 0x0000ffff, /* src_mask */
512 0x0000ffff, /* dst_mask */
513 FALSE
), /* pcrel_offset */
515 /* Section displacement. */
516 HOWTO (R_MIPS_SCN_DISP
, /* type */
518 2, /* size (0 = byte, 1 = short, 2 = long) */
520 FALSE
, /* pc_relative */
522 complain_overflow_dont
, /* complain_on_overflow */
523 _bfd_mips_elf_generic_reloc
, /* special_function */
524 "R_MIPS_SCN_DISP", /* name */
525 TRUE
, /* partial_inplace */
526 0xffffffff, /* src_mask */
527 0xffffffff, /* dst_mask */
528 FALSE
), /* pcrel_offset */
530 EMPTY_HOWTO (R_MIPS_REL16
),
531 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
532 EMPTY_HOWTO (R_MIPS_PJUMP
),
533 EMPTY_HOWTO (R_MIPS_RELGOT
),
535 /* Protected jump conversion. This is an optimization hint. No
536 relocation is required for correctness. */
537 HOWTO (R_MIPS_JALR
, /* type */
539 2, /* size (0 = byte, 1 = short, 2 = long) */
541 FALSE
, /* pc_relative */
543 complain_overflow_dont
, /* complain_on_overflow */
544 _bfd_mips_elf_generic_reloc
, /* special_function */
545 "R_MIPS_JALR", /* name */
546 FALSE
, /* partial_inplace */
547 0x00000000, /* src_mask */
548 0x00000000, /* dst_mask */
549 FALSE
), /* pcrel_offset */
551 /* TLS GD/LD dynamic relocations. */
552 HOWTO (R_MIPS_TLS_DTPMOD32
, /* type */
554 2, /* size (0 = byte, 1 = short, 2 = long) */
556 FALSE
, /* pc_relative */
558 complain_overflow_dont
, /* complain_on_overflow */
559 _bfd_mips_elf_generic_reloc
, /* special_function */
560 "R_MIPS_TLS_DTPMOD32", /* name */
561 TRUE
, /* partial_inplace */
562 0xffffffff, /* src_mask */
563 0xffffffff, /* dst_mask */
564 FALSE
), /* pcrel_offset */
566 HOWTO (R_MIPS_TLS_DTPREL32
, /* type */
568 2, /* size (0 = byte, 1 = short, 2 = long) */
570 FALSE
, /* pc_relative */
572 complain_overflow_dont
, /* complain_on_overflow */
573 _bfd_mips_elf_generic_reloc
, /* special_function */
574 "R_MIPS_TLS_DTPREL32", /* name */
575 TRUE
, /* partial_inplace */
576 0xffffffff, /* src_mask */
577 0xffffffff, /* dst_mask */
578 FALSE
), /* pcrel_offset */
580 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64
),
581 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64
),
583 /* TLS general dynamic variable reference. */
584 HOWTO (R_MIPS_TLS_GD
, /* type */
586 2, /* size (0 = byte, 1 = short, 2 = long) */
588 FALSE
, /* pc_relative */
590 complain_overflow_signed
, /* complain_on_overflow */
591 _bfd_mips_elf_generic_reloc
, /* special_function */
592 "R_MIPS_TLS_GD", /* name */
593 TRUE
, /* partial_inplace */
594 0x0000ffff, /* src_mask */
595 0x0000ffff, /* dst_mask */
596 FALSE
), /* pcrel_offset */
598 /* TLS local dynamic variable reference. */
599 HOWTO (R_MIPS_TLS_LDM
, /* type */
601 2, /* size (0 = byte, 1 = short, 2 = long) */
603 FALSE
, /* pc_relative */
605 complain_overflow_signed
, /* complain_on_overflow */
606 _bfd_mips_elf_generic_reloc
, /* special_function */
607 "R_MIPS_TLS_LDM", /* name */
608 TRUE
, /* partial_inplace */
609 0x0000ffff, /* src_mask */
610 0x0000ffff, /* dst_mask */
611 FALSE
), /* pcrel_offset */
613 /* TLS local dynamic offset. */
614 HOWTO (R_MIPS_TLS_DTPREL_HI16
, /* type */
616 2, /* size (0 = byte, 1 = short, 2 = long) */
618 FALSE
, /* pc_relative */
620 complain_overflow_signed
, /* complain_on_overflow */
621 _bfd_mips_elf_generic_reloc
, /* special_function */
622 "R_MIPS_TLS_DTPREL_HI16", /* name */
623 TRUE
, /* partial_inplace */
624 0x0000ffff, /* src_mask */
625 0x0000ffff, /* dst_mask */
626 FALSE
), /* pcrel_offset */
628 /* TLS local dynamic offset. */
629 HOWTO (R_MIPS_TLS_DTPREL_LO16
, /* type */
631 2, /* size (0 = byte, 1 = short, 2 = long) */
633 FALSE
, /* pc_relative */
635 complain_overflow_signed
, /* complain_on_overflow */
636 _bfd_mips_elf_generic_reloc
, /* special_function */
637 "R_MIPS_TLS_DTPREL_LO16", /* name */
638 TRUE
, /* partial_inplace */
639 0x0000ffff, /* src_mask */
640 0x0000ffff, /* dst_mask */
641 FALSE
), /* pcrel_offset */
643 /* TLS thread pointer offset. */
644 HOWTO (R_MIPS_TLS_GOTTPREL
, /* type */
646 2, /* size (0 = byte, 1 = short, 2 = long) */
648 FALSE
, /* pc_relative */
650 complain_overflow_signed
, /* complain_on_overflow */
651 _bfd_mips_elf_generic_reloc
, /* special_function */
652 "R_MIPS_TLS_GOTTPREL", /* name */
653 TRUE
, /* partial_inplace */
654 0x0000ffff, /* src_mask */
655 0x0000ffff, /* dst_mask */
656 FALSE
), /* pcrel_offset */
658 /* TLS IE dynamic relocations. */
659 HOWTO (R_MIPS_TLS_TPREL32
, /* type */
661 2, /* size (0 = byte, 1 = short, 2 = long) */
663 FALSE
, /* pc_relative */
665 complain_overflow_dont
, /* complain_on_overflow */
666 _bfd_mips_elf_generic_reloc
, /* special_function */
667 "R_MIPS_TLS_TPREL32", /* name */
668 TRUE
, /* partial_inplace */
669 0xffffffff, /* src_mask */
670 0xffffffff, /* dst_mask */
671 FALSE
), /* pcrel_offset */
673 EMPTY_HOWTO (R_MIPS_TLS_TPREL64
),
675 /* TLS thread pointer offset. */
676 HOWTO (R_MIPS_TLS_TPREL_HI16
, /* type */
678 2, /* size (0 = byte, 1 = short, 2 = long) */
680 FALSE
, /* pc_relative */
682 complain_overflow_signed
, /* complain_on_overflow */
683 _bfd_mips_elf_generic_reloc
, /* special_function */
684 "R_MIPS_TLS_TPREL_HI16", /* name */
685 TRUE
, /* partial_inplace */
686 0x0000ffff, /* src_mask */
687 0x0000ffff, /* dst_mask */
688 FALSE
), /* pcrel_offset */
690 /* TLS thread pointer offset. */
691 HOWTO (R_MIPS_TLS_TPREL_LO16
, /* type */
693 2, /* size (0 = byte, 1 = short, 2 = long) */
695 FALSE
, /* pc_relative */
697 complain_overflow_signed
, /* complain_on_overflow */
698 _bfd_mips_elf_generic_reloc
, /* special_function */
699 "R_MIPS_TLS_TPREL_LO16", /* name */
700 TRUE
, /* partial_inplace */
701 0x0000ffff, /* src_mask */
702 0x0000ffff, /* dst_mask */
703 FALSE
), /* pcrel_offset */
706 /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
707 is a hack to make the linker think that we need 64 bit values. */
708 static reloc_howto_type elf_mips_ctor64_howto
=
709 HOWTO (R_MIPS_64
, /* type */
711 4, /* size (0 = byte, 1 = short, 2 = long) */
713 FALSE
, /* pc_relative */
715 complain_overflow_signed
, /* complain_on_overflow */
716 mips32_64bit_reloc
, /* special_function */
717 "R_MIPS_64", /* name */
718 TRUE
, /* partial_inplace */
719 0xffffffff, /* src_mask */
720 0xffffffff, /* dst_mask */
721 FALSE
); /* pcrel_offset */
723 static reloc_howto_type elf_mips16_howto_table_rel
[] =
725 /* The reloc used for the mips16 jump instruction. */
726 HOWTO (R_MIPS16_26
, /* type */
728 2, /* size (0 = byte, 1 = short, 2 = long) */
730 FALSE
, /* pc_relative */
732 complain_overflow_dont
, /* complain_on_overflow */
733 /* This needs complex overflow
734 detection, because the upper four
735 bits must match the PC. */
736 mips16_jump_reloc
, /* special_function */
737 "R_MIPS16_26", /* name */
738 TRUE
, /* partial_inplace */
739 0x3ffffff, /* src_mask */
740 0x3ffffff, /* dst_mask */
741 FALSE
), /* pcrel_offset */
743 /* The reloc used for the mips16 gprel instruction. */
744 HOWTO (R_MIPS16_GPREL
, /* type */
746 2, /* size (0 = byte, 1 = short, 2 = long) */
748 FALSE
, /* pc_relative */
750 complain_overflow_signed
, /* complain_on_overflow */
751 mips16_gprel_reloc
, /* special_function */
752 "R_MIPS16_GPREL", /* name */
753 TRUE
, /* partial_inplace */
754 0x0000ffff, /* src_mask */
755 0x0000ffff, /* dst_mask */
756 FALSE
), /* pcrel_offset */
758 /* A placeholder for MIPS16 reference to global offset table. */
759 EMPTY_HOWTO (R_MIPS16_GOT16
),
761 /* A placeholder for MIPS16 16 bit call through global offset table. */
762 EMPTY_HOWTO (R_MIPS16_CALL16
),
764 /* MIPS16 high 16 bits of symbol value. */
765 HOWTO (R_MIPS16_HI16
, /* type */
767 2, /* size (0 = byte, 1 = short, 2 = long) */
769 FALSE
, /* pc_relative */
771 complain_overflow_dont
, /* complain_on_overflow */
772 _bfd_mips_elf_hi16_reloc
, /* special_function */
773 "R_MIPS16_HI16", /* name */
774 TRUE
, /* partial_inplace */
775 0x0000ffff, /* src_mask */
776 0x0000ffff, /* dst_mask */
777 FALSE
), /* pcrel_offset */
779 /* MIPS16 low 16 bits of symbol value. */
780 HOWTO (R_MIPS16_LO16
, /* type */
782 2, /* size (0 = byte, 1 = short, 2 = long) */
784 FALSE
, /* pc_relative */
786 complain_overflow_dont
, /* complain_on_overflow */
787 _bfd_mips_elf_lo16_reloc
, /* special_function */
788 "R_MIPS16_LO16", /* name */
789 TRUE
, /* partial_inplace */
790 0x0000ffff, /* src_mask */
791 0x0000ffff, /* dst_mask */
792 FALSE
), /* pcrel_offset */
795 /* 16 bit offset for pc-relative branches. */
796 static reloc_howto_type elf_mips_gnu_rel16_s2
=
797 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
801 TRUE
, /* pc_relative */
803 complain_overflow_signed
, /* complain_on_overflow */
804 _bfd_mips_elf_generic_reloc
, /* special_function */
805 "R_MIPS_GNU_REL16_S2", /* name */
806 TRUE
, /* partial_inplace */
807 0xffff, /* src_mask */
808 0xffff, /* dst_mask */
809 TRUE
); /* pcrel_offset */
811 /* 32 bit pc-relative. This was a GNU extension used by embedded-PIC.
812 It was co-opted by mips-linux for exception-handling data. It is no
813 longer used, but should continue to be supported by the linker for
814 backward compatibility. (GCC stopped using it in May, 2004.) */
815 static reloc_howto_type elf_mips_gnu_pcrel32
=
816 HOWTO (R_MIPS_PC32
, /* type */
818 2, /* size (0 = byte, 1 = short, 2 = long) */
820 TRUE
, /* pc_relative */
822 complain_overflow_signed
, /* complain_on_overflow */
823 _bfd_mips_elf_generic_reloc
, /* special_function */
824 "R_MIPS_PC32", /* name */
825 TRUE
, /* partial_inplace */
826 0xffffffff, /* src_mask */
827 0xffffffff, /* dst_mask */
828 TRUE
); /* pcrel_offset */
830 /* GNU extension to record C++ vtable hierarchy */
831 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
832 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
834 2, /* size (0 = byte, 1 = short, 2 = long) */
836 FALSE
, /* pc_relative */
838 complain_overflow_dont
, /* complain_on_overflow */
839 NULL
, /* special_function */
840 "R_MIPS_GNU_VTINHERIT", /* name */
841 FALSE
, /* partial_inplace */
844 FALSE
); /* pcrel_offset */
846 /* GNU extension to record C++ vtable member usage */
847 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
848 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
850 2, /* size (0 = byte, 1 = short, 2 = long) */
852 FALSE
, /* pc_relative */
854 complain_overflow_dont
, /* complain_on_overflow */
855 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
856 "R_MIPS_GNU_VTENTRY", /* name */
857 FALSE
, /* partial_inplace */
860 FALSE
); /* pcrel_offset */
862 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
863 dangerous relocation. */
866 mips_elf_assign_gp (bfd
*output_bfd
, bfd_vma
*pgp
)
872 /* If we've already figured out what GP will be, just return it. */
873 *pgp
= _bfd_get_gp_value (output_bfd
);
877 count
= bfd_get_symcount (output_bfd
);
878 sym
= bfd_get_outsymbols (output_bfd
);
880 /* The linker script will have created a symbol named `_gp' with the
881 appropriate value. */
886 for (i
= 0; i
< count
; i
++, sym
++)
888 register const char *name
;
890 name
= bfd_asymbol_name (*sym
);
891 if (*name
== '_' && strcmp (name
, "_gp") == 0)
893 *pgp
= bfd_asymbol_value (*sym
);
894 _bfd_set_gp_value (output_bfd
, *pgp
);
902 /* Only get the error once. */
904 _bfd_set_gp_value (output_bfd
, *pgp
);
911 /* We have to figure out the gp value, so that we can adjust the
912 symbol value correctly. We look up the symbol _gp in the output
913 BFD. If we can't find it, we're stuck. We cache it in the ELF
914 target data. We don't need to adjust the symbol value for an
915 external symbol if we are producing relocatable output. */
917 static bfd_reloc_status_type
918 mips_elf_final_gp (bfd
*output_bfd
, asymbol
*symbol
, bfd_boolean relocatable
,
919 char **error_message
, bfd_vma
*pgp
)
921 if (bfd_is_und_section (symbol
->section
)
925 return bfd_reloc_undefined
;
928 *pgp
= _bfd_get_gp_value (output_bfd
);
931 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
935 /* Make up a value. */
936 *pgp
= symbol
->section
->output_section
->vma
+ 0x4000;
937 _bfd_set_gp_value (output_bfd
, *pgp
);
939 else if (!mips_elf_assign_gp (output_bfd
, pgp
))
942 (char *) _("GP relative relocation when _gp not defined");
943 return bfd_reloc_dangerous
;
950 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
951 become the offset from the gp register. This function also handles
952 R_MIPS_LITERAL relocations, although those can be handled more
953 cleverly because the entries in the .lit8 and .lit4 sections can be
956 bfd_reloc_status_type
957 _bfd_mips_elf32_gprel16_reloc (bfd
*abfd
, arelent
*reloc_entry
,
958 asymbol
*symbol
, void *data
,
959 asection
*input_section
, bfd
*output_bfd
,
960 char **error_message
)
962 bfd_boolean relocatable
;
963 bfd_reloc_status_type ret
;
966 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
967 if (reloc_entry
->howto
->type
== R_MIPS_LITERAL
968 && output_bfd
!= NULL
969 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
970 && (symbol
->flags
& BSF_LOCAL
) != 0)
972 *error_message
= (char *)
973 _("literal relocation occurs for an external symbol");
974 return bfd_reloc_outofrange
;
977 if (output_bfd
!= NULL
)
982 output_bfd
= symbol
->section
->output_section
->owner
;
985 ret
= mips_elf_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
987 if (ret
!= bfd_reloc_ok
)
990 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
991 input_section
, relocatable
,
995 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
996 become the offset from the gp register. */
998 static bfd_reloc_status_type
999 mips_elf_gprel32_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1000 void *data
, asection
*input_section
, bfd
*output_bfd
,
1001 char **error_message
)
1003 bfd_boolean relocatable
;
1004 bfd_reloc_status_type ret
;
1007 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1008 if (output_bfd
!= NULL
1009 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1010 && (symbol
->flags
& BSF_LOCAL
) != 0)
1012 *error_message
= (char *)
1013 _("32bits gp relative relocation occurs for an external symbol");
1014 return bfd_reloc_outofrange
;
1017 if (output_bfd
!= NULL
)
1021 relocatable
= FALSE
;
1022 output_bfd
= symbol
->section
->output_section
->owner
;
1025 ret
= mips_elf_final_gp (output_bfd
, symbol
, relocatable
,
1026 error_message
, &gp
);
1027 if (ret
!= bfd_reloc_ok
)
1030 return gprel32_with_gp (abfd
, symbol
, reloc_entry
, input_section
,
1031 relocatable
, data
, gp
);
1034 static bfd_reloc_status_type
1035 gprel32_with_gp (bfd
*abfd
, asymbol
*symbol
, arelent
*reloc_entry
,
1036 asection
*input_section
, bfd_boolean relocatable
,
1037 void *data
, bfd_vma gp
)
1042 if (bfd_is_com_section (symbol
->section
))
1045 relocation
= symbol
->value
;
1047 relocation
+= symbol
->section
->output_section
->vma
;
1048 relocation
+= symbol
->section
->output_offset
;
1050 if (reloc_entry
->address
> bfd_get_section_limit (abfd
, input_section
))
1051 return bfd_reloc_outofrange
;
1053 /* Set val to the offset into the section or symbol. */
1054 val
= reloc_entry
->addend
;
1056 if (reloc_entry
->howto
->partial_inplace
)
1057 val
+= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1059 /* Adjust val for the final section location and GP value. If we
1060 are producing relocatable output, we don't want to do this for
1061 an external symbol. */
1063 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1064 val
+= relocation
- gp
;
1066 if (reloc_entry
->howto
->partial_inplace
)
1067 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
1069 reloc_entry
->addend
= val
;
1072 reloc_entry
->address
+= input_section
->output_offset
;
1074 return bfd_reloc_ok
;
1077 /* Handle a 64 bit reloc in a 32 bit MIPS ELF file. These are
1078 generated when addresses are 64 bits. The upper 32 bits are a simple
1081 static bfd_reloc_status_type
1082 mips32_64bit_reloc (bfd
*abfd
, arelent
*reloc_entry
,
1083 asymbol
*symbol ATTRIBUTE_UNUSED
,
1084 void *data
, asection
*input_section
,
1085 bfd
*output_bfd
, char **error_message
)
1087 bfd_reloc_status_type r
;
1092 /* Do a normal 32 bit relocation on the lower 32 bits. */
1093 reloc32
= *reloc_entry
;
1094 if (bfd_big_endian (abfd
))
1095 reloc32
.address
+= 4;
1096 reloc32
.howto
= &elf_mips_howto_table_rel
[R_MIPS_32
];
1097 r
= bfd_perform_relocation (abfd
, &reloc32
, data
, input_section
,
1098 output_bfd
, error_message
);
1100 /* Sign extend into the upper 32 bits. */
1101 val
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc32
.address
);
1102 if ((val
& 0x80000000) != 0)
1106 addr
= reloc_entry
->address
;
1107 if (bfd_little_endian (abfd
))
1109 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ addr
);
1114 /* Handle a mips16 jump. */
1116 static bfd_reloc_status_type
1117 mips16_jump_reloc (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*reloc_entry
,
1118 asymbol
*symbol
, void *data ATTRIBUTE_UNUSED
,
1119 asection
*input_section
, bfd
*output_bfd
,
1120 char **error_message ATTRIBUTE_UNUSED
)
1122 if (output_bfd
!= NULL
1123 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1124 && reloc_entry
->addend
== 0)
1126 reloc_entry
->address
+= input_section
->output_offset
;
1127 return bfd_reloc_ok
;
1132 static bfd_boolean warned
;
1135 (*_bfd_error_handler
)
1136 (_("Linking mips16 objects into %s format is not supported"),
1137 bfd_get_target (input_section
->output_section
->owner
));
1141 return bfd_reloc_undefined
;
1144 /* Handle a mips16 GP relative reloc. */
1146 static bfd_reloc_status_type
1147 mips16_gprel_reloc (bfd
*abfd
, arelent
*reloc_entry
, asymbol
*symbol
,
1148 void *data
, asection
*input_section
, bfd
*output_bfd
,
1149 char **error_message
)
1151 bfd_boolean relocatable
;
1152 bfd_reloc_status_type ret
;
1156 /* If we're relocating, and this is an external symbol, we don't want
1157 to change anything. */
1158 if (output_bfd
!= NULL
1159 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1160 && (symbol
->flags
& BSF_LOCAL
) != 0)
1162 reloc_entry
->address
+= input_section
->output_offset
;
1163 return bfd_reloc_ok
;
1166 if (output_bfd
!= NULL
)
1170 relocatable
= FALSE
;
1171 output_bfd
= symbol
->section
->output_section
->owner
;
1174 ret
= mips_elf_final_gp (output_bfd
, symbol
, relocatable
, error_message
,
1176 if (ret
!= bfd_reloc_ok
)
1179 location
= (bfd_byte
*) data
+ reloc_entry
->address
;
1180 _bfd_mips16_elf_reloc_unshuffle (abfd
, reloc_entry
->howto
->type
, FALSE
,
1182 ret
= _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1183 input_section
, relocatable
,
1185 _bfd_mips16_elf_reloc_shuffle (abfd
, reloc_entry
->howto
->type
, !relocatable
,
1191 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1193 struct elf_reloc_map
{
1194 bfd_reloc_code_real_type bfd_val
;
1195 enum elf_mips_reloc_type elf_val
;
1198 static const struct elf_reloc_map mips_reloc_map
[] =
1200 { BFD_RELOC_NONE
, R_MIPS_NONE
},
1201 { BFD_RELOC_16
, R_MIPS_16
},
1202 { BFD_RELOC_32
, R_MIPS_32
},
1203 /* There is no BFD reloc for R_MIPS_REL32. */
1204 { BFD_RELOC_64
, R_MIPS_64
},
1205 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
1206 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
1207 { BFD_RELOC_LO16
, R_MIPS_LO16
},
1208 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
1209 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
1210 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
1211 { BFD_RELOC_16_PCREL_S2
, R_MIPS_PC16
},
1212 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
1213 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
1214 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
1215 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
1216 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
1217 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
1218 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
1219 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
1220 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
1221 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
},
1222 { BFD_RELOC_MIPS_TLS_DTPMOD32
, R_MIPS_TLS_DTPMOD32
},
1223 { BFD_RELOC_MIPS_TLS_DTPREL32
, R_MIPS_TLS_DTPREL32
},
1224 { BFD_RELOC_MIPS_TLS_DTPMOD64
, R_MIPS_TLS_DTPMOD64
},
1225 { BFD_RELOC_MIPS_TLS_DTPREL64
, R_MIPS_TLS_DTPREL64
},
1226 { BFD_RELOC_MIPS_TLS_GD
, R_MIPS_TLS_GD
},
1227 { BFD_RELOC_MIPS_TLS_LDM
, R_MIPS_TLS_LDM
},
1228 { BFD_RELOC_MIPS_TLS_DTPREL_HI16
, R_MIPS_TLS_DTPREL_HI16
},
1229 { BFD_RELOC_MIPS_TLS_DTPREL_LO16
, R_MIPS_TLS_DTPREL_LO16
},
1230 { BFD_RELOC_MIPS_TLS_GOTTPREL
, R_MIPS_TLS_GOTTPREL
},
1231 { BFD_RELOC_MIPS_TLS_TPREL32
, R_MIPS_TLS_TPREL32
},
1232 { BFD_RELOC_MIPS_TLS_TPREL64
, R_MIPS_TLS_TPREL64
},
1233 { BFD_RELOC_MIPS_TLS_TPREL_HI16
, R_MIPS_TLS_TPREL_HI16
},
1234 { BFD_RELOC_MIPS_TLS_TPREL_LO16
, R_MIPS_TLS_TPREL_LO16
}
1237 static const struct elf_reloc_map mips16_reloc_map
[] =
1239 { BFD_RELOC_MIPS16_JMP
, R_MIPS16_26
- R_MIPS16_min
},
1240 { BFD_RELOC_MIPS16_GPREL
, R_MIPS16_GPREL
- R_MIPS16_min
},
1241 { BFD_RELOC_MIPS16_HI16_S
, R_MIPS16_HI16
- R_MIPS16_min
},
1242 { BFD_RELOC_MIPS16_LO16
, R_MIPS16_LO16
- R_MIPS16_min
},
1245 /* Given a BFD reloc type, return a howto structure. */
1247 static reloc_howto_type
*
1248 bfd_elf32_bfd_reloc_type_lookup (bfd
*abfd
, bfd_reloc_code_real_type code
)
1251 reloc_howto_type
*howto_table
= elf_mips_howto_table_rel
;
1252 reloc_howto_type
*howto16_table
= elf_mips16_howto_table_rel
;
1254 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
1257 if (mips_reloc_map
[i
].bfd_val
== code
)
1258 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
1261 for (i
= 0; i
< sizeof (mips16_reloc_map
) / sizeof (struct elf_reloc_map
);
1264 if (mips16_reloc_map
[i
].bfd_val
== code
)
1265 return &howto16_table
[(int) mips16_reloc_map
[i
].elf_val
];
1271 bfd_set_error (bfd_error_bad_value
);
1274 case BFD_RELOC_CTOR
:
1275 /* We need to handle BFD_RELOC_CTOR specially.
1276 Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
1277 size of addresses of the ABI. */
1278 if ((elf_elfheader (abfd
)->e_flags
& (E_MIPS_ABI_O64
1279 | E_MIPS_ABI_EABI64
)) != 0)
1280 return &elf_mips_ctor64_howto
;
1282 return &howto_table
[(int) R_MIPS_32
];
1284 case BFD_RELOC_VTABLE_INHERIT
:
1285 return &elf_mips_gnu_vtinherit_howto
;
1286 case BFD_RELOC_VTABLE_ENTRY
:
1287 return &elf_mips_gnu_vtentry_howto
;
1288 case BFD_RELOC_32_PCREL
:
1289 return &elf_mips_gnu_pcrel32
;
1293 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1295 static reloc_howto_type
*
1296 mips_elf32_rtype_to_howto (unsigned int r_type
,
1297 bfd_boolean rela_p ATTRIBUTE_UNUSED
)
1301 case R_MIPS_GNU_VTINHERIT
:
1302 return &elf_mips_gnu_vtinherit_howto
;
1303 case R_MIPS_GNU_VTENTRY
:
1304 return &elf_mips_gnu_vtentry_howto
;
1305 case R_MIPS_GNU_REL16_S2
:
1306 return &elf_mips_gnu_rel16_s2
;
1308 return &elf_mips_gnu_pcrel32
;
1310 if (r_type
>= R_MIPS16_min
&& r_type
< R_MIPS16_max
)
1311 return &elf_mips16_howto_table_rel
[r_type
- R_MIPS16_min
];
1312 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
1313 return &elf_mips_howto_table_rel
[r_type
];
1317 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1320 mips_info_to_howto_rel (bfd
*abfd
, arelent
*cache_ptr
, Elf_Internal_Rela
*dst
)
1322 unsigned int r_type
;
1324 r_type
= ELF32_R_TYPE (dst
->r_info
);
1325 cache_ptr
->howto
= mips_elf32_rtype_to_howto (r_type
, FALSE
);
1327 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1328 value for the object file. We get the addend now, rather than
1329 when we do the relocation, because the symbol manipulations done
1330 by the linker may cause us to lose track of the input BFD. */
1331 if (((*cache_ptr
->sym_ptr_ptr
)->flags
& BSF_SECTION_SYM
) != 0
1332 && (r_type
== (unsigned int) R_MIPS_GPREL16
1333 || r_type
== (unsigned int) R_MIPS_LITERAL
))
1334 cache_ptr
->addend
= elf_gp (abfd
);
1337 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
1340 mips_info_to_howto_rela (bfd
*abfd
, arelent
*cache_ptr
, Elf_Internal_Rela
*dst
)
1342 mips_info_to_howto_rel (abfd
, cache_ptr
, dst
);
1344 /* If we ever need to do any extra processing with dst->r_addend
1345 (the field omitted in an Elf_Internal_Rel) we can do it here. */
1348 /* Determine whether a symbol is global for the purposes of splitting
1349 the symbol table into global symbols and local symbols. At least
1350 on Irix 5, this split must be between section symbols and all other
1351 symbols. On most ELF targets the split is between static symbols
1352 and externally visible symbols. */
1355 mips_elf_sym_is_global (bfd
*abfd ATTRIBUTE_UNUSED
, asymbol
*sym
)
1357 if (SGI_COMPAT (abfd
))
1358 return (sym
->flags
& BSF_SECTION_SYM
) == 0;
1360 return ((sym
->flags
& (BSF_GLOBAL
| BSF_WEAK
)) != 0
1361 || bfd_is_und_section (bfd_get_section (sym
))
1362 || bfd_is_com_section (bfd_get_section (sym
)));
1365 /* Set the right machine number for a MIPS ELF file. */
1368 mips_elf32_object_p (bfd
*abfd
)
1372 /* Irix 5 and 6 are broken. Object file symbol tables are not always
1373 sorted correctly such that local symbols precede global symbols,
1374 and the sh_info field in the symbol table is not always right. */
1375 if (SGI_COMPAT (abfd
))
1376 elf_bad_symtab (abfd
) = TRUE
;
1378 if (ABI_N32_P (abfd
))
1381 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
1382 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
1387 /* MIPS ELF local labels start with '$', not 'L'. */
1390 mips_elf_is_local_label_name (bfd
*abfd
, const char *name
)
1395 /* On Irix 6, the labels go back to starting with '.', so we accept
1396 the generic ELF local label syntax as well. */
1397 return _bfd_elf_is_local_label_name (abfd
, name
);
1400 /* Support for core dump NOTE sections. */
1402 elf32_mips_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
1407 switch (note
->descsz
)
1412 case 256: /* Linux/MIPS */
1414 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
1417 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
1426 /* Make a ".reg/999" section. */
1427 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
1428 size
, note
->descpos
+ offset
);
1432 elf32_mips_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
1434 switch (note
->descsz
)
1439 case 128: /* Linux/MIPS elf_prpsinfo */
1440 elf_tdata (abfd
)->core_program
1441 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 32, 16);
1442 elf_tdata (abfd
)->core_command
1443 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 48, 80);
1446 /* Note that for some reason, a spurious space is tacked
1447 onto the end of the args in some (at least one anyway)
1448 implementations, so strip it off if it exists. */
1451 char *command
= elf_tdata (abfd
)->core_command
;
1452 int n
= strlen (command
);
1454 if (0 < n
&& command
[n
- 1] == ' ')
1455 command
[n
- 1] = '\0';
1461 /* Depending on the target vector we generate some version of Irix
1462 executables or "normal" MIPS ELF ABI executables. */
1463 static irix_compat_t
1464 elf32_mips_irix_compat (bfd
*abfd
)
1466 if ((abfd
->xvec
== &bfd_elf32_bigmips_vec
)
1467 || (abfd
->xvec
== &bfd_elf32_littlemips_vec
))
1473 /* ECOFF swapping routines. These are used when dealing with the
1474 .mdebug section, which is in the ECOFF debugging format. */
1475 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap
= {
1476 /* Symbol table magic number. */
1478 /* Alignment of debugging information. E.g., 4. */
1480 /* Sizes of external symbolic information. */
1481 sizeof (struct hdr_ext
),
1482 sizeof (struct dnr_ext
),
1483 sizeof (struct pdr_ext
),
1484 sizeof (struct sym_ext
),
1485 sizeof (struct opt_ext
),
1486 sizeof (struct fdr_ext
),
1487 sizeof (struct rfd_ext
),
1488 sizeof (struct ext_ext
),
1489 /* Functions to swap in external symbolic data. */
1498 _bfd_ecoff_swap_tir_in
,
1499 _bfd_ecoff_swap_rndx_in
,
1500 /* Functions to swap out external symbolic data. */
1509 _bfd_ecoff_swap_tir_out
,
1510 _bfd_ecoff_swap_rndx_out
,
1511 /* Function to read in symbolic data. */
1512 _bfd_mips_elf_read_ecoff_info
1515 #define ELF_ARCH bfd_arch_mips
1516 #define ELF_MACHINE_CODE EM_MIPS
1518 #define elf_backend_collect TRUE
1519 #define elf_backend_type_change_ok TRUE
1520 #define elf_backend_can_gc_sections TRUE
1521 #define elf_info_to_howto mips_info_to_howto_rela
1522 #define elf_info_to_howto_rel mips_info_to_howto_rel
1523 #define elf_backend_sym_is_global mips_elf_sym_is_global
1524 #define elf_backend_object_p mips_elf32_object_p
1525 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
1526 #define elf_backend_section_processing _bfd_mips_elf_section_processing
1527 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
1528 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
1529 #define elf_backend_section_from_bfd_section \
1530 _bfd_mips_elf_section_from_bfd_section
1531 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
1532 #define elf_backend_link_output_symbol_hook \
1533 _bfd_mips_elf_link_output_symbol_hook
1534 #define elf_backend_create_dynamic_sections \
1535 _bfd_mips_elf_create_dynamic_sections
1536 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
1537 #define elf_backend_adjust_dynamic_symbol \
1538 _bfd_mips_elf_adjust_dynamic_symbol
1539 #define elf_backend_always_size_sections \
1540 _bfd_mips_elf_always_size_sections
1541 #define elf_backend_size_dynamic_sections \
1542 _bfd_mips_elf_size_dynamic_sections
1543 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
1544 #define elf_backend_finish_dynamic_symbol \
1545 _bfd_mips_elf_finish_dynamic_symbol
1546 #define elf_backend_finish_dynamic_sections \
1547 _bfd_mips_elf_finish_dynamic_sections
1548 #define elf_backend_final_write_processing \
1549 _bfd_mips_elf_final_write_processing
1550 #define elf_backend_additional_program_headers \
1551 _bfd_mips_elf_additional_program_headers
1552 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
1553 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
1554 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
1555 #define elf_backend_copy_indirect_symbol \
1556 _bfd_mips_elf_copy_indirect_symbol
1557 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
1558 #define elf_backend_grok_prstatus elf32_mips_grok_prstatus
1559 #define elf_backend_grok_psinfo elf32_mips_grok_psinfo
1560 #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
1562 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
1563 #define elf_backend_may_use_rel_p 1
1564 #define elf_backend_may_use_rela_p 0
1565 #define elf_backend_default_use_rela_p 0
1566 #define elf_backend_sign_extend_vma TRUE
1568 #define elf_backend_discard_info _bfd_mips_elf_discard_info
1569 #define elf_backend_ignore_discarded_relocs \
1570 _bfd_mips_elf_ignore_discarded_relocs
1571 #define elf_backend_mips_irix_compat elf32_mips_irix_compat
1572 #define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
1573 #define bfd_elf32_bfd_is_local_label_name \
1574 mips_elf_is_local_label_name
1575 #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
1576 #define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
1577 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
1578 #define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
1579 #define bfd_elf32_bfd_get_relocated_section_contents \
1580 _bfd_elf_mips_get_relocated_section_contents
1581 #define bfd_elf32_bfd_link_hash_table_create \
1582 _bfd_mips_elf_link_hash_table_create
1583 #define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
1584 #define bfd_elf32_bfd_merge_private_bfd_data \
1585 _bfd_mips_elf_merge_private_bfd_data
1586 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
1587 #define bfd_elf32_bfd_print_private_bfd_data \
1588 _bfd_mips_elf_print_private_bfd_data
1590 /* Support for SGI-ish mips targets. */
1591 #define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec
1592 #define TARGET_LITTLE_NAME "elf32-littlemips"
1593 #define TARGET_BIG_SYM bfd_elf32_bigmips_vec
1594 #define TARGET_BIG_NAME "elf32-bigmips"
1596 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
1597 a value of 0x1000, and we are compatible. */
1598 #define ELF_MAXPAGESIZE 0x1000
1600 #include "elf32-target.h"
1602 /* Support for traditional mips targets. */
1603 #undef TARGET_LITTLE_SYM
1604 #undef TARGET_LITTLE_NAME
1605 #undef TARGET_BIG_SYM
1606 #undef TARGET_BIG_NAME
1608 #undef ELF_MAXPAGESIZE
1610 #define TARGET_LITTLE_SYM bfd_elf32_tradlittlemips_vec
1611 #define TARGET_LITTLE_NAME "elf32-tradlittlemips"
1612 #define TARGET_BIG_SYM bfd_elf32_tradbigmips_vec
1613 #define TARGET_BIG_NAME "elf32-tradbigmips"
1615 /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
1616 page sizes of up to that limit, so we need to respect it. */
1617 #define ELF_MAXPAGESIZE 0x10000
1618 #define elf32_bed elf32_tradbed
1620 /* Include the target file again for this target. */
1621 #include "elf32-target.h"