1 /* MIPS-specific support for 32-bit ELF
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 2003 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 bfd_reloc_status_type gprel32_with_gp
59 PARAMS ((bfd
*, asymbol
*, arelent
*, asection
*, bfd_boolean
, PTR
,
61 static bfd_reloc_status_type mips_elf_gprel32_reloc
62 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
63 static bfd_reloc_status_type mips32_64bit_reloc
64 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
65 static reloc_howto_type
*bfd_elf32_bfd_reloc_type_lookup
66 PARAMS ((bfd
*, bfd_reloc_code_real_type
));
67 static reloc_howto_type
*mips_elf32_rtype_to_howto
68 PARAMS ((unsigned int, bfd_boolean
));
69 static void mips_info_to_howto_rel
70 PARAMS ((bfd
*, arelent
*, Elf_Internal_Rela
*));
71 static void mips_info_to_howto_rela
72 PARAMS ((bfd
*, arelent
*, Elf_Internal_Rela
*));
73 static bfd_boolean mips_elf_sym_is_global
74 PARAMS ((bfd
*, asymbol
*));
75 static bfd_boolean mips_elf32_object_p
77 static bfd_boolean mips_elf_is_local_label_name
78 PARAMS ((bfd
*, const char *));
79 static bfd_reloc_status_type mips16_jump_reloc
80 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
81 static bfd_reloc_status_type mips16_gprel_reloc
82 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
83 static bfd_reloc_status_type mips_elf_final_gp
84 PARAMS ((bfd
*, asymbol
*, bfd_boolean
, char **, bfd_vma
*));
85 static bfd_boolean mips_elf_assign_gp
86 PARAMS ((bfd
*, bfd_vma
*));
87 static bfd_boolean elf32_mips_grok_prstatus
88 PARAMS ((bfd
*, Elf_Internal_Note
*));
89 static bfd_boolean elf32_mips_grok_psinfo
90 PARAMS ((bfd
*, Elf_Internal_Note
*));
91 static irix_compat_t elf32_mips_irix_compat
94 extern const bfd_target bfd_elf32_bigmips_vec
;
95 extern const bfd_target bfd_elf32_littlemips_vec
;
97 /* Nonzero if ABFD is using the N32 ABI. */
98 #define ABI_N32_P(abfd) \
99 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
101 /* Whether we are trying to be compatible with IRIX at all. */
102 #define SGI_COMPAT(abfd) \
103 (elf32_mips_irix_compat (abfd) != ict_none)
105 /* The number of local .got entries we reserve. */
106 #define MIPS_RESERVED_GOTNO (2)
108 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
109 from smaller values. Start with zero, widen, *then* decrement. */
110 #define MINUS_ONE (((bfd_vma)0) - 1)
112 /* The relocation table used for SHT_REL sections. */
114 static reloc_howto_type elf_mips_howto_table_rel
[] =
117 HOWTO (R_MIPS_NONE
, /* type */
119 0, /* size (0 = byte, 1 = short, 2 = long) */
121 FALSE
, /* pc_relative */
123 complain_overflow_dont
, /* complain_on_overflow */
124 mips_elf_generic_reloc
, /* special_function */
125 "R_MIPS_NONE", /* name */
126 FALSE
, /* partial_inplace */
129 FALSE
), /* pcrel_offset */
131 /* 16 bit relocation. */
132 HOWTO (R_MIPS_16
, /* type */
134 2, /* size (0 = byte, 1 = short, 2 = long) */
136 FALSE
, /* pc_relative */
138 complain_overflow_signed
, /* complain_on_overflow */
139 mips_elf_generic_reloc
, /* special_function */
140 "R_MIPS_16", /* name */
141 TRUE
, /* partial_inplace */
142 0x0000ffff, /* src_mask */
143 0x0000ffff, /* dst_mask */
144 FALSE
), /* pcrel_offset */
146 /* 32 bit relocation. */
147 HOWTO (R_MIPS_32
, /* type */
149 2, /* size (0 = byte, 1 = short, 2 = long) */
151 FALSE
, /* pc_relative */
153 complain_overflow_dont
, /* complain_on_overflow */
154 mips_elf_generic_reloc
, /* special_function */
155 "R_MIPS_32", /* name */
156 TRUE
, /* partial_inplace */
157 0xffffffff, /* src_mask */
158 0xffffffff, /* dst_mask */
159 FALSE
), /* pcrel_offset */
161 /* 32 bit symbol relative relocation. */
162 HOWTO (R_MIPS_REL32
, /* type */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
166 FALSE
, /* pc_relative */
168 complain_overflow_dont
, /* complain_on_overflow */
169 mips_elf_generic_reloc
, /* special_function */
170 "R_MIPS_REL32", /* name */
171 TRUE
, /* partial_inplace */
172 0xffffffff, /* src_mask */
173 0xffffffff, /* dst_mask */
174 FALSE
), /* pcrel_offset */
176 /* 26 bit jump address. */
177 HOWTO (R_MIPS_26
, /* type */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
181 FALSE
, /* pc_relative */
183 complain_overflow_dont
, /* complain_on_overflow */
184 /* This needs complex overflow
185 detection, because the upper four
186 bits must match the PC + 4. */
187 mips_elf_generic_reloc
, /* special_function */
188 "R_MIPS_26", /* name */
189 TRUE
, /* partial_inplace */
190 0x03ffffff, /* src_mask */
191 0x03ffffff, /* dst_mask */
192 FALSE
), /* pcrel_offset */
194 /* High 16 bits of symbol value. */
195 HOWTO (R_MIPS_HI16
, /* type */
197 2, /* size (0 = byte, 1 = short, 2 = long) */
199 FALSE
, /* pc_relative */
201 complain_overflow_dont
, /* complain_on_overflow */
202 mips_elf_hi16_reloc
, /* special_function */
203 "R_MIPS_HI16", /* name */
204 TRUE
, /* partial_inplace */
205 0x0000ffff, /* src_mask */
206 0x0000ffff, /* dst_mask */
207 FALSE
), /* pcrel_offset */
209 /* Low 16 bits of symbol value. */
210 HOWTO (R_MIPS_LO16
, /* type */
212 2, /* size (0 = byte, 1 = short, 2 = long) */
214 FALSE
, /* pc_relative */
216 complain_overflow_dont
, /* complain_on_overflow */
217 mips_elf_lo16_reloc
, /* special_function */
218 "R_MIPS_LO16", /* name */
219 TRUE
, /* partial_inplace */
220 0x0000ffff, /* src_mask */
221 0x0000ffff, /* dst_mask */
222 FALSE
), /* pcrel_offset */
224 /* GP relative reference. */
225 HOWTO (R_MIPS_GPREL16
, /* type */
227 2, /* size (0 = byte, 1 = short, 2 = long) */
229 FALSE
, /* pc_relative */
231 complain_overflow_signed
, /* complain_on_overflow */
232 _bfd_mips_elf32_gprel16_reloc
, /* special_function */
233 "R_MIPS_GPREL16", /* name */
234 TRUE
, /* partial_inplace */
235 0x0000ffff, /* src_mask */
236 0x0000ffff, /* dst_mask */
237 FALSE
), /* pcrel_offset */
239 /* Reference to literal section. */
240 HOWTO (R_MIPS_LITERAL
, /* type */
242 2, /* size (0 = byte, 1 = short, 2 = long) */
244 FALSE
, /* pc_relative */
246 complain_overflow_signed
, /* complain_on_overflow */
247 _bfd_mips_elf32_gprel16_reloc
, /* special_function */
248 "R_MIPS_LITERAL", /* name */
249 TRUE
, /* partial_inplace */
250 0x0000ffff, /* src_mask */
251 0x0000ffff, /* dst_mask */
252 FALSE
), /* pcrel_offset */
254 /* Reference to global offset table. */
255 HOWTO (R_MIPS_GOT16
, /* type */
257 2, /* size (0 = byte, 1 = short, 2 = long) */
259 FALSE
, /* pc_relative */
261 complain_overflow_signed
, /* complain_on_overflow */
262 mips_elf_got16_reloc
, /* special_function */
263 "R_MIPS_GOT16", /* name */
264 TRUE
, /* partial_inplace */
265 0x0000ffff, /* src_mask */
266 0x0000ffff, /* dst_mask */
267 FALSE
), /* pcrel_offset */
269 /* 16 bit PC relative reference. */
270 HOWTO (R_MIPS_PC16
, /* type */
272 2, /* size (0 = byte, 1 = short, 2 = long) */
274 TRUE
, /* pc_relative */
276 complain_overflow_signed
, /* complain_on_overflow */
277 mips_elf_generic_reloc
, /* special_function */
278 "R_MIPS_PC16", /* name */
279 TRUE
, /* partial_inplace */
280 0x0000ffff, /* src_mask */
281 0x0000ffff, /* dst_mask */
282 TRUE
), /* pcrel_offset */
284 /* 16 bit call through global offset table. */
285 HOWTO (R_MIPS_CALL16
, /* type */
287 2, /* size (0 = byte, 1 = short, 2 = long) */
289 FALSE
, /* pc_relative */
291 complain_overflow_signed
, /* complain_on_overflow */
292 mips_elf_generic_reloc
, /* special_function */
293 "R_MIPS_CALL16", /* name */
294 TRUE
, /* partial_inplace */
295 0x0000ffff, /* src_mask */
296 0x0000ffff, /* dst_mask */
297 FALSE
), /* pcrel_offset */
299 /* 32 bit GP relative reference. */
300 HOWTO (R_MIPS_GPREL32
, /* type */
302 2, /* size (0 = byte, 1 = short, 2 = long) */
304 FALSE
, /* pc_relative */
306 complain_overflow_dont
, /* complain_on_overflow */
307 mips_elf_gprel32_reloc
, /* special_function */
308 "R_MIPS_GPREL32", /* name */
309 TRUE
, /* partial_inplace */
310 0xffffffff, /* src_mask */
311 0xffffffff, /* dst_mask */
312 FALSE
), /* pcrel_offset */
314 /* The remaining relocs are defined on Irix 5, although they are
315 not defined by the ABI. */
320 /* A 5 bit shift field. */
321 HOWTO (R_MIPS_SHIFT5
, /* type */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
325 FALSE
, /* pc_relative */
327 complain_overflow_bitfield
, /* complain_on_overflow */
328 mips_elf_generic_reloc
, /* special_function */
329 "R_MIPS_SHIFT5", /* name */
330 TRUE
, /* partial_inplace */
331 0x000007c0, /* src_mask */
332 0x000007c0, /* dst_mask */
333 FALSE
), /* pcrel_offset */
335 /* A 6 bit shift field. */
336 /* FIXME: This is not handled correctly; a special function is
337 needed to put the most significant bit in the right place. */
338 HOWTO (R_MIPS_SHIFT6
, /* type */
340 2, /* size (0 = byte, 1 = short, 2 = long) */
342 FALSE
, /* pc_relative */
344 complain_overflow_bitfield
, /* complain_on_overflow */
345 mips_elf_generic_reloc
, /* special_function */
346 "R_MIPS_SHIFT6", /* name */
347 TRUE
, /* partial_inplace */
348 0x000007c4, /* src_mask */
349 0x000007c4, /* dst_mask */
350 FALSE
), /* pcrel_offset */
352 /* A 64 bit relocation. */
353 HOWTO (R_MIPS_64
, /* type */
355 4, /* size (0 = byte, 1 = short, 2 = long) */
357 FALSE
, /* pc_relative */
359 complain_overflow_dont
, /* complain_on_overflow */
360 mips32_64bit_reloc
, /* special_function */
361 "R_MIPS_64", /* name */
362 TRUE
, /* partial_inplace */
363 MINUS_ONE
, /* src_mask */
364 MINUS_ONE
, /* dst_mask */
365 FALSE
), /* pcrel_offset */
367 /* Displacement in the global offset table. */
368 HOWTO (R_MIPS_GOT_DISP
, /* type */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
372 FALSE
, /* pc_relative */
374 complain_overflow_signed
, /* complain_on_overflow */
375 mips_elf_generic_reloc
, /* special_function */
376 "R_MIPS_GOT_DISP", /* name */
377 TRUE
, /* partial_inplace */
378 0x0000ffff, /* src_mask */
379 0x0000ffff, /* dst_mask */
380 FALSE
), /* pcrel_offset */
382 /* Displacement to page pointer in the global offset table. */
383 HOWTO (R_MIPS_GOT_PAGE
, /* type */
385 2, /* size (0 = byte, 1 = short, 2 = long) */
387 FALSE
, /* pc_relative */
389 complain_overflow_signed
, /* complain_on_overflow */
390 mips_elf_generic_reloc
, /* special_function */
391 "R_MIPS_GOT_PAGE", /* name */
392 TRUE
, /* partial_inplace */
393 0x0000ffff, /* src_mask */
394 0x0000ffff, /* dst_mask */
395 FALSE
), /* pcrel_offset */
397 /* Offset from page pointer in the global offset table. */
398 HOWTO (R_MIPS_GOT_OFST
, /* type */
400 2, /* size (0 = byte, 1 = short, 2 = long) */
402 FALSE
, /* pc_relative */
404 complain_overflow_signed
, /* complain_on_overflow */
405 mips_elf_generic_reloc
, /* special_function */
406 "R_MIPS_GOT_OFST", /* name */
407 TRUE
, /* partial_inplace */
408 0x0000ffff, /* src_mask */
409 0x0000ffff, /* dst_mask */
410 FALSE
), /* pcrel_offset */
412 /* High 16 bits of displacement in global offset table. */
413 HOWTO (R_MIPS_GOT_HI16
, /* type */
415 2, /* size (0 = byte, 1 = short, 2 = long) */
417 FALSE
, /* pc_relative */
419 complain_overflow_dont
, /* complain_on_overflow */
420 mips_elf_generic_reloc
, /* special_function */
421 "R_MIPS_GOT_HI16", /* name */
422 TRUE
, /* partial_inplace */
423 0x0000ffff, /* src_mask */
424 0x0000ffff, /* dst_mask */
425 FALSE
), /* pcrel_offset */
427 /* Low 16 bits of displacement in global offset table. */
428 HOWTO (R_MIPS_GOT_LO16
, /* type */
430 2, /* size (0 = byte, 1 = short, 2 = long) */
432 FALSE
, /* pc_relative */
434 complain_overflow_dont
, /* complain_on_overflow */
435 mips_elf_generic_reloc
, /* special_function */
436 "R_MIPS_GOT_LO16", /* name */
437 TRUE
, /* partial_inplace */
438 0x0000ffff, /* src_mask */
439 0x0000ffff, /* dst_mask */
440 FALSE
), /* pcrel_offset */
442 /* 64 bit subtraction. Used in the N32 ABI. */
443 HOWTO (R_MIPS_SUB
, /* type */
445 4, /* size (0 = byte, 1 = short, 2 = long) */
447 FALSE
, /* pc_relative */
449 complain_overflow_dont
, /* complain_on_overflow */
450 mips_elf_generic_reloc
, /* special_function */
451 "R_MIPS_SUB", /* name */
452 TRUE
, /* partial_inplace */
453 MINUS_ONE
, /* src_mask */
454 MINUS_ONE
, /* dst_mask */
455 FALSE
), /* pcrel_offset */
457 /* Used to cause the linker to insert and delete instructions? */
458 EMPTY_HOWTO (R_MIPS_INSERT_A
),
459 EMPTY_HOWTO (R_MIPS_INSERT_B
),
460 EMPTY_HOWTO (R_MIPS_DELETE
),
462 /* Get the higher value of a 64 bit addend. */
463 HOWTO (R_MIPS_HIGHER
, /* type */
465 2, /* size (0 = byte, 1 = short, 2 = long) */
467 FALSE
, /* pc_relative */
469 complain_overflow_dont
, /* complain_on_overflow */
470 mips_elf_generic_reloc
, /* special_function */
471 "R_MIPS_HIGHER", /* name */
472 TRUE
, /* partial_inplace */
473 0x0000ffff, /* src_mask */
474 0x0000ffff, /* dst_mask */
475 FALSE
), /* pcrel_offset */
477 /* Get the highest value of a 64 bit addend. */
478 HOWTO (R_MIPS_HIGHEST
, /* 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_HIGHEST", /* name */
487 TRUE
, /* partial_inplace */
488 0x0000ffff, /* src_mask */
489 0x0000ffff, /* dst_mask */
490 FALSE
), /* pcrel_offset */
492 /* High 16 bits of displacement in global offset table. */
493 HOWTO (R_MIPS_CALL_HI16
, /* type */
495 2, /* size (0 = byte, 1 = short, 2 = long) */
497 FALSE
, /* pc_relative */
499 complain_overflow_dont
, /* complain_on_overflow */
500 mips_elf_generic_reloc
, /* special_function */
501 "R_MIPS_CALL_HI16", /* name */
502 TRUE
, /* partial_inplace */
503 0x0000ffff, /* src_mask */
504 0x0000ffff, /* dst_mask */
505 FALSE
), /* pcrel_offset */
507 /* Low 16 bits of displacement in global offset table. */
508 HOWTO (R_MIPS_CALL_LO16
, /* type */
510 2, /* size (0 = byte, 1 = short, 2 = long) */
512 FALSE
, /* pc_relative */
514 complain_overflow_dont
, /* complain_on_overflow */
515 mips_elf_generic_reloc
, /* special_function */
516 "R_MIPS_CALL_LO16", /* name */
517 TRUE
, /* partial_inplace */
518 0x0000ffff, /* src_mask */
519 0x0000ffff, /* dst_mask */
520 FALSE
), /* pcrel_offset */
522 /* Section displacement. */
523 HOWTO (R_MIPS_SCN_DISP
, /* type */
525 2, /* size (0 = byte, 1 = short, 2 = long) */
527 FALSE
, /* pc_relative */
529 complain_overflow_dont
, /* complain_on_overflow */
530 mips_elf_generic_reloc
, /* special_function */
531 "R_MIPS_SCN_DISP", /* name */
532 TRUE
, /* partial_inplace */
533 0xffffffff, /* src_mask */
534 0xffffffff, /* dst_mask */
535 FALSE
), /* pcrel_offset */
537 EMPTY_HOWTO (R_MIPS_REL16
),
538 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE
),
539 EMPTY_HOWTO (R_MIPS_PJUMP
),
540 EMPTY_HOWTO (R_MIPS_RELGOT
),
542 /* Protected jump conversion. This is an optimization hint. No
543 relocation is required for correctness. */
544 HOWTO (R_MIPS_JALR
, /* type */
546 2, /* size (0 = byte, 1 = short, 2 = long) */
548 FALSE
, /* pc_relative */
550 complain_overflow_dont
, /* complain_on_overflow */
551 mips_elf_generic_reloc
, /* special_function */
552 "R_MIPS_JALR", /* name */
553 FALSE
, /* partial_inplace */
554 0x00000000, /* src_mask */
555 0x00000000, /* dst_mask */
556 FALSE
), /* pcrel_offset */
559 /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
560 is a hack to make the linker think that we need 64 bit values. */
561 static reloc_howto_type elf_mips_ctor64_howto
=
562 HOWTO (R_MIPS_64
, /* type */
564 4, /* size (0 = byte, 1 = short, 2 = long) */
566 FALSE
, /* pc_relative */
568 complain_overflow_signed
, /* complain_on_overflow */
569 mips32_64bit_reloc
, /* special_function */
570 "R_MIPS_64", /* name */
571 TRUE
, /* partial_inplace */
572 0xffffffff, /* src_mask */
573 0xffffffff, /* dst_mask */
574 FALSE
); /* pcrel_offset */
576 /* The reloc used for the mips16 jump instruction. */
577 static reloc_howto_type elf_mips16_jump_howto
=
578 HOWTO (R_MIPS16_26
, /* type */
580 2, /* size (0 = byte, 1 = short, 2 = long) */
582 FALSE
, /* pc_relative */
584 complain_overflow_dont
, /* complain_on_overflow */
585 /* This needs complex overflow
586 detection, because the upper four
587 bits must match the PC. */
588 mips16_jump_reloc
, /* special_function */
589 "R_MIPS16_26", /* name */
590 TRUE
, /* partial_inplace */
591 0x3ffffff, /* src_mask */
592 0x3ffffff, /* dst_mask */
593 FALSE
); /* pcrel_offset */
595 /* The reloc used for the mips16 gprel instruction. */
596 static reloc_howto_type elf_mips16_gprel_howto
=
597 HOWTO (R_MIPS16_GPREL
, /* type */
599 2, /* size (0 = byte, 1 = short, 2 = long) */
601 FALSE
, /* pc_relative */
603 complain_overflow_signed
, /* complain_on_overflow */
604 mips16_gprel_reloc
, /* special_function */
605 "R_MIPS16_GPREL", /* name */
606 TRUE
, /* partial_inplace */
607 0x07ff001f, /* src_mask */
608 0x07ff001f, /* dst_mask */
609 FALSE
); /* pcrel_offset */
611 /* GNU extensions for embedded-pic. */
612 /* High 16 bits of symbol value, pc-relative. */
613 static reloc_howto_type elf_mips_gnu_rel_hi16
=
614 HOWTO (R_MIPS_GNU_REL_HI16
, /* type */
616 2, /* size (0 = byte, 1 = short, 2 = long) */
618 TRUE
, /* pc_relative */
620 complain_overflow_dont
, /* complain_on_overflow */
621 mips_elf_hi16_reloc
, /* special_function */
622 "R_MIPS_GNU_REL_HI16", /* name */
623 TRUE
, /* partial_inplace */
624 0xffff, /* src_mask */
625 0xffff, /* dst_mask */
626 TRUE
); /* pcrel_offset */
628 /* Low 16 bits of symbol value, pc-relative. */
629 static reloc_howto_type elf_mips_gnu_rel_lo16
=
630 HOWTO (R_MIPS_GNU_REL_LO16
, /* type */
632 2, /* size (0 = byte, 1 = short, 2 = long) */
634 TRUE
, /* pc_relative */
636 complain_overflow_dont
, /* complain_on_overflow */
637 mips_elf_lo16_reloc
, /* special_function */
638 "R_MIPS_GNU_REL_LO16", /* name */
639 TRUE
, /* partial_inplace */
640 0xffff, /* src_mask */
641 0xffff, /* dst_mask */
642 TRUE
); /* pcrel_offset */
644 /* 16 bit offset for pc-relative branches. */
645 static reloc_howto_type elf_mips_gnu_rel16_s2
=
646 HOWTO (R_MIPS_GNU_REL16_S2
, /* type */
648 2, /* size (0 = byte, 1 = short, 2 = long) */
650 TRUE
, /* pc_relative */
652 complain_overflow_signed
, /* complain_on_overflow */
653 mips_elf_generic_reloc
, /* special_function */
654 "R_MIPS_GNU_REL16_S2", /* name */
655 TRUE
, /* partial_inplace */
656 0xffff, /* src_mask */
657 0xffff, /* dst_mask */
658 TRUE
); /* pcrel_offset */
660 /* 64 bit pc-relative. */
661 static reloc_howto_type elf_mips_gnu_pcrel64
=
662 HOWTO (R_MIPS_PC64
, /* type */
664 4, /* size (0 = byte, 1 = short, 2 = long) */
666 TRUE
, /* pc_relative */
668 complain_overflow_signed
, /* complain_on_overflow */
669 mips_elf_generic_reloc
, /* special_function */
670 "R_MIPS_PC64", /* name */
671 TRUE
, /* partial_inplace */
672 MINUS_ONE
, /* src_mask */
673 MINUS_ONE
, /* dst_mask */
674 TRUE
); /* pcrel_offset */
676 /* 32 bit pc-relative. */
677 static reloc_howto_type elf_mips_gnu_pcrel32
=
678 HOWTO (R_MIPS_PC32
, /* type */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
682 TRUE
, /* pc_relative */
684 complain_overflow_signed
, /* complain_on_overflow */
685 mips_elf_generic_reloc
, /* special_function */
686 "R_MIPS_PC32", /* name */
687 TRUE
, /* partial_inplace */
688 0xffffffff, /* src_mask */
689 0xffffffff, /* dst_mask */
690 TRUE
); /* pcrel_offset */
692 /* GNU extension to record C++ vtable hierarchy */
693 static reloc_howto_type elf_mips_gnu_vtinherit_howto
=
694 HOWTO (R_MIPS_GNU_VTINHERIT
, /* type */
696 2, /* size (0 = byte, 1 = short, 2 = long) */
698 FALSE
, /* pc_relative */
700 complain_overflow_dont
, /* complain_on_overflow */
701 NULL
, /* special_function */
702 "R_MIPS_GNU_VTINHERIT", /* name */
703 FALSE
, /* partial_inplace */
706 FALSE
); /* pcrel_offset */
708 /* GNU extension to record C++ vtable member usage */
709 static reloc_howto_type elf_mips_gnu_vtentry_howto
=
710 HOWTO (R_MIPS_GNU_VTENTRY
, /* type */
712 2, /* size (0 = byte, 1 = short, 2 = long) */
714 FALSE
, /* pc_relative */
716 complain_overflow_dont
, /* complain_on_overflow */
717 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
718 "R_MIPS_GNU_VTENTRY", /* name */
719 FALSE
, /* partial_inplace */
722 FALSE
); /* pcrel_offset */
724 /* We use this instead of bfd_elf_generic_reloc because the latter
725 gets the handling of zero addends wrong. */
726 static bfd_reloc_status_type
727 mips_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
728 output_bfd
, error_message
)
729 bfd
*abfd ATTRIBUTE_UNUSED
;
730 arelent
*reloc_entry
;
732 PTR data ATTRIBUTE_UNUSED
;
733 asection
*input_section
;
735 char **error_message ATTRIBUTE_UNUSED
;
737 /* If we're relocating, and this is an external symbol, we don't want
738 to change anything. */
739 if (output_bfd
!= (bfd
*) NULL
740 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
741 && (symbol
->flags
& BSF_LOCAL
) != 0)
743 reloc_entry
->address
+= input_section
->output_offset
;
747 /* Just go on, nothing to see here. */
748 return bfd_reloc_continue
;
751 /* Do a R_MIPS_HI16 relocation. This has to be done in combination
752 with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
753 the HI16. Here we just save the information we need; we do the
754 actual relocation when we see the LO16.
756 MIPS ELF requires that the LO16 immediately follow the HI16. As a
757 GNU extension, for non-pc-relative relocations, we permit an
758 arbitrary number of HI16 relocs to be associated with a single LO16
759 reloc. This extension permits gcc to output the HI and LO relocs
762 This cannot be done for PC-relative relocations because both the HI16
763 and LO16 parts of the relocations must be done relative to the LO16
764 part, and there can be carry to or borrow from the HI16 part. */
768 struct mips_hi16
*next
;
773 /* FIXME: This should not be a static variable. */
775 static struct mips_hi16
*mips_hi16_list
;
777 static bfd_reloc_status_type
778 mips_elf_hi16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
779 output_bfd
, error_message
)
780 bfd
*abfd ATTRIBUTE_UNUSED
;
781 arelent
*reloc_entry
;
784 asection
*input_section
;
786 char **error_message
;
788 bfd_reloc_status_type ret
;
792 /* If we're relocating, and this is an external symbol, we don't want
793 to change anything. */
794 if (output_bfd
!= (bfd
*) NULL
795 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
796 && (symbol
->flags
& BSF_LOCAL
) != 0)
798 reloc_entry
->address
+= input_section
->output_offset
;
804 if (strcmp (bfd_asymbol_name (symbol
), "_gp_disp") == 0)
806 bfd_boolean relocateable
;
809 if (ret
== bfd_reloc_undefined
)
812 if (output_bfd
!= NULL
)
816 relocateable
= FALSE
;
817 output_bfd
= symbol
->section
->output_section
->owner
;
820 ret
= mips_elf_final_gp (output_bfd
, symbol
, relocateable
,
822 if (ret
!= bfd_reloc_ok
)
825 relocation
= gp
- reloc_entry
->address
;
829 if (bfd_is_und_section (symbol
->section
)
830 && output_bfd
== (bfd
*) NULL
)
831 ret
= bfd_reloc_undefined
;
833 if (bfd_is_com_section (symbol
->section
))
836 relocation
= symbol
->value
;
839 relocation
+= symbol
->section
->output_section
->vma
;
840 relocation
+= symbol
->section
->output_offset
;
841 relocation
+= reloc_entry
->addend
;
843 if (reloc_entry
->address
> input_section
->_cooked_size
)
844 return bfd_reloc_outofrange
;
846 /* Save the information, and let LO16 do the actual relocation. */
847 n
= (struct mips_hi16
*) bfd_malloc ((bfd_size_type
) sizeof *n
);
849 return bfd_reloc_outofrange
;
850 n
->addr
= (bfd_byte
*) data
+ reloc_entry
->address
;
851 n
->addend
= relocation
;
852 n
->next
= mips_hi16_list
;
855 if (output_bfd
!= (bfd
*) NULL
)
856 reloc_entry
->address
+= input_section
->output_offset
;
861 /* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit
862 inplace relocation; this function exists in order to do the
863 R_MIPS_HI16 relocation described above. */
865 static bfd_reloc_status_type
866 mips_elf_lo16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
867 output_bfd
, error_message
)
869 arelent
*reloc_entry
;
872 asection
*input_section
;
874 char **error_message
;
876 arelent gp_disp_relent
;
878 if (mips_hi16_list
!= NULL
)
888 struct mips_hi16
*next
;
890 /* Do the HI16 relocation. Note that we actually don't need
891 to know anything about the LO16 itself, except where to
892 find the low 16 bits of the addend needed by the LO16. */
893 insn
= bfd_get_32 (abfd
, l
->addr
);
894 vallo
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
896 /* The low order 16 bits are always treated as a signed
898 vallo
= ((vallo
& 0xffff) ^ 0x8000) - 0x8000;
899 val
= ((insn
& 0xffff) << 16) + vallo
;
902 /* If PC-relative, we need to subtract out the address of the LO
903 half of the HI/LO. (The actual relocation is relative
904 to that instruction.) */
905 if (reloc_entry
->howto
->pc_relative
)
906 val
-= reloc_entry
->address
;
908 /* At this point, "val" has the value of the combined HI/LO
909 pair. If the low order 16 bits (which will be used for
910 the LO16 insn) are negative, then we will need an
911 adjustment for the high order 16 bits. */
913 val
= (val
>> 16) & 0xffff;
915 insn
&= ~ (bfd_vma
) 0xffff;
917 bfd_put_32 (abfd
, (bfd_vma
) insn
, l
->addr
);
919 if (strcmp (bfd_asymbol_name (symbol
), "_gp_disp") == 0)
921 gp_disp_relent
= *reloc_entry
;
922 reloc_entry
= &gp_disp_relent
;
923 reloc_entry
->addend
= l
->addend
;
931 mips_hi16_list
= NULL
;
933 else if (strcmp (bfd_asymbol_name (symbol
), "_gp_disp") == 0)
935 bfd_reloc_status_type ret
;
936 bfd_vma gp
, relocation
;
938 /* FIXME: Does this case ever occur? */
940 ret
= mips_elf_final_gp (output_bfd
, symbol
, TRUE
, error_message
, &gp
);
941 if (ret
!= bfd_reloc_ok
)
944 relocation
= gp
- reloc_entry
->address
;
945 relocation
+= symbol
->section
->output_section
->vma
;
946 relocation
+= symbol
->section
->output_offset
;
947 relocation
+= reloc_entry
->addend
;
949 if (reloc_entry
->address
> input_section
->_cooked_size
)
950 return bfd_reloc_outofrange
;
952 gp_disp_relent
= *reloc_entry
;
953 reloc_entry
= &gp_disp_relent
;
954 reloc_entry
->addend
= relocation
- 4;
957 /* Now do the LO16 reloc in the usual way. */
958 return mips_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
959 input_section
, output_bfd
, error_message
);
962 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
963 table used for PIC code. If the symbol is an external symbol, the
964 instruction is modified to contain the offset of the appropriate
965 entry in the global offset table. If the symbol is a section
966 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
967 addends are combined to form the real addend against the section
968 symbol; the GOT16 is modified to contain the offset of an entry in
969 the global offset table, and the LO16 is modified to offset it
970 appropriately. Thus an offset larger than 16 bits requires a
971 modified value in the global offset table.
973 This implementation suffices for the assembler, but the linker does
974 not yet know how to create global offset tables. */
976 static bfd_reloc_status_type
977 mips_elf_got16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
978 output_bfd
, error_message
)
980 arelent
*reloc_entry
;
983 asection
*input_section
;
985 char **error_message
;
987 /* If we're relocating, and this is an external symbol, we don't want
988 to change anything. */
989 if (output_bfd
!= (bfd
*) NULL
990 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
991 && (symbol
->flags
& BSF_LOCAL
) != 0)
993 reloc_entry
->address
+= input_section
->output_offset
;
997 return mips_elf_hi16_reloc (abfd
, reloc_entry
, symbol
, data
,
998 input_section
, output_bfd
, error_message
);
1001 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1002 dangerous relocation. */
1005 mips_elf_assign_gp (output_bfd
, pgp
)
1013 /* If we've already figured out what GP will be, just return it. */
1014 *pgp
= _bfd_get_gp_value (output_bfd
);
1018 count
= bfd_get_symcount (output_bfd
);
1019 sym
= bfd_get_outsymbols (output_bfd
);
1021 /* The linker script will have created a symbol named `_gp' with the
1022 appropriate value. */
1023 if (sym
== (asymbol
**) NULL
)
1027 for (i
= 0; i
< count
; i
++, sym
++)
1029 register const char *name
;
1031 name
= bfd_asymbol_name (*sym
);
1032 if (*name
== '_' && strcmp (name
, "_gp") == 0)
1034 *pgp
= bfd_asymbol_value (*sym
);
1035 _bfd_set_gp_value (output_bfd
, *pgp
);
1043 /* Only get the error once. */
1045 _bfd_set_gp_value (output_bfd
, *pgp
);
1052 /* We have to figure out the gp value, so that we can adjust the
1053 symbol value correctly. We look up the symbol _gp in the output
1054 BFD. If we can't find it, we're stuck. We cache it in the ELF
1055 target data. We don't need to adjust the symbol value for an
1056 external symbol if we are producing relocateable output. */
1058 static bfd_reloc_status_type
1059 mips_elf_final_gp (output_bfd
, symbol
, relocateable
, error_message
, pgp
)
1062 bfd_boolean relocateable
;
1063 char **error_message
;
1066 if (bfd_is_und_section (symbol
->section
)
1070 return bfd_reloc_undefined
;
1073 *pgp
= _bfd_get_gp_value (output_bfd
);
1076 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
1080 /* Make up a value. */
1081 *pgp
= symbol
->section
->output_section
->vma
+ 0x4000;
1082 _bfd_set_gp_value (output_bfd
, *pgp
);
1084 else if (!mips_elf_assign_gp (output_bfd
, pgp
))
1087 (char *) _("GP relative relocation when _gp not defined");
1088 return bfd_reloc_dangerous
;
1092 return bfd_reloc_ok
;
1095 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1096 become the offset from the gp register. This function also handles
1097 R_MIPS_LITERAL relocations, although those can be handled more
1098 cleverly because the entries in the .lit8 and .lit4 sections can be
1101 bfd_reloc_status_type
1102 _bfd_mips_elf32_gprel16_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1103 output_bfd
, error_message
)
1105 arelent
*reloc_entry
;
1108 asection
*input_section
;
1110 char **error_message
;
1112 bfd_boolean relocateable
;
1113 bfd_reloc_status_type ret
;
1116 /* If we're relocating, and this is an external symbol, we don't want
1117 to change anything. */
1118 if (output_bfd
!= (bfd
*) NULL
1119 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1120 && (symbol
->flags
& BSF_LOCAL
) != 0)
1122 reloc_entry
->address
+= input_section
->output_offset
;
1123 return bfd_reloc_ok
;
1126 if (output_bfd
!= (bfd
*) NULL
)
1127 relocateable
= TRUE
;
1130 relocateable
= FALSE
;
1131 output_bfd
= symbol
->section
->output_section
->owner
;
1134 ret
= mips_elf_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1136 if (ret
!= bfd_reloc_ok
)
1139 return _bfd_mips_elf_gprel16_with_gp (abfd
, symbol
, reloc_entry
,
1140 input_section
, relocateable
,
1144 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1145 become the offset from the gp register. */
1147 static bfd_reloc_status_type
1148 mips_elf_gprel32_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1149 output_bfd
, error_message
)
1151 arelent
*reloc_entry
;
1154 asection
*input_section
;
1156 char **error_message
;
1158 bfd_boolean relocateable
;
1159 bfd_reloc_status_type ret
;
1162 /* If we're relocating, and this is an external symbol, we don't want
1163 to change anything. */
1164 if (output_bfd
!= (bfd
*) NULL
1165 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1166 && (symbol
->flags
& BSF_LOCAL
) != 0)
1168 *error_message
= (char *)
1169 _("32bits gp relative relocation occurs for an external symbol");
1170 return bfd_reloc_outofrange
;
1173 if (output_bfd
!= (bfd
*) NULL
)
1174 relocateable
= TRUE
;
1177 relocateable
= FALSE
;
1178 output_bfd
= symbol
->section
->output_section
->owner
;
1181 ret
= mips_elf_final_gp (output_bfd
, symbol
, relocateable
,
1182 error_message
, &gp
);
1183 if (ret
!= bfd_reloc_ok
)
1186 return gprel32_with_gp (abfd
, symbol
, reloc_entry
, input_section
,
1187 relocateable
, data
, gp
);
1190 static bfd_reloc_status_type
1191 gprel32_with_gp (abfd
, symbol
, reloc_entry
, input_section
, relocateable
, data
,
1195 arelent
*reloc_entry
;
1196 asection
*input_section
;
1197 bfd_boolean relocateable
;
1204 if (bfd_is_com_section (symbol
->section
))
1207 relocation
= symbol
->value
;
1209 relocation
+= symbol
->section
->output_section
->vma
;
1210 relocation
+= symbol
->section
->output_offset
;
1212 if (reloc_entry
->address
> input_section
->_cooked_size
)
1213 return bfd_reloc_outofrange
;
1215 /* Set val to the offset into the section or symbol. */
1216 val
= reloc_entry
->addend
;
1218 if (reloc_entry
->howto
->partial_inplace
)
1219 val
+= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1221 /* Adjust val for the final section location and GP value. If we
1222 are producing relocateable output, we don't want to do this for
1223 an external symbol. */
1225 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1226 val
+= relocation
- gp
;
1228 if (reloc_entry
->howto
->partial_inplace
)
1229 bfd_put_32 (abfd
, val
, (bfd_byte
*) data
+ reloc_entry
->address
);
1231 reloc_entry
->addend
= val
;
1234 reloc_entry
->address
+= input_section
->output_offset
;
1236 return bfd_reloc_ok
;
1239 /* Handle a 64 bit reloc in a 32 bit MIPS ELF file. These are
1240 generated when addresses are 64 bits. The upper 32 bits are a simple
1243 static bfd_reloc_status_type
1244 mips32_64bit_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1245 output_bfd
, error_message
)
1247 arelent
*reloc_entry
;
1250 asection
*input_section
;
1252 char **error_message
;
1254 bfd_reloc_status_type r
;
1259 r
= mips_elf_generic_reloc (abfd
, reloc_entry
, symbol
, data
,
1260 input_section
, output_bfd
, error_message
);
1261 if (r
!= bfd_reloc_continue
)
1264 /* Do a normal 32 bit relocation on the lower 32 bits. */
1265 reloc32
= *reloc_entry
;
1266 if (bfd_big_endian (abfd
))
1267 reloc32
.address
+= 4;
1268 reloc32
.howto
= &elf_mips_howto_table_rel
[R_MIPS_32
];
1269 r
= bfd_perform_relocation (abfd
, &reloc32
, data
, input_section
,
1270 output_bfd
, error_message
);
1272 /* Sign extend into the upper 32 bits. */
1273 val
= bfd_get_32 (abfd
, (bfd_byte
*) data
+ reloc32
.address
);
1274 if ((val
& 0x80000000) != 0)
1278 addr
= reloc_entry
->address
;
1279 if (bfd_little_endian (abfd
))
1281 bfd_put_32 (abfd
, (bfd_vma
) val
, (bfd_byte
*) data
+ addr
);
1286 /* Handle a mips16 jump. */
1288 static bfd_reloc_status_type
1289 mips16_jump_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1290 output_bfd
, error_message
)
1291 bfd
*abfd ATTRIBUTE_UNUSED
;
1292 arelent
*reloc_entry
;
1294 PTR data ATTRIBUTE_UNUSED
;
1295 asection
*input_section
;
1297 char **error_message ATTRIBUTE_UNUSED
;
1299 if (output_bfd
!= (bfd
*) NULL
1300 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1301 && reloc_entry
->addend
== 0)
1303 reloc_entry
->address
+= input_section
->output_offset
;
1304 return bfd_reloc_ok
;
1309 static bfd_boolean warned
;
1312 (*_bfd_error_handler
)
1313 (_("Linking mips16 objects into %s format is not supported"),
1314 bfd_get_target (input_section
->output_section
->owner
));
1318 return bfd_reloc_undefined
;
1321 /* Handle a mips16 GP relative reloc. */
1323 static bfd_reloc_status_type
1324 mips16_gprel_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
1325 output_bfd
, error_message
)
1327 arelent
*reloc_entry
;
1330 asection
*input_section
;
1332 char **error_message
;
1334 bfd_boolean relocateable
;
1335 bfd_reloc_status_type ret
;
1337 unsigned short extend
= 0;
1338 unsigned short insn
= 0;
1342 /* If we're relocating, and this is an external symbol, we don't want
1343 to change anything. */
1344 if (output_bfd
!= NULL
1345 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
1346 && (symbol
->flags
& BSF_LOCAL
) != 0)
1348 reloc_entry
->address
+= input_section
->output_offset
;
1349 return bfd_reloc_ok
;
1352 if (output_bfd
!= NULL
)
1353 relocateable
= TRUE
;
1356 relocateable
= FALSE
;
1357 output_bfd
= symbol
->section
->output_section
->owner
;
1360 ret
= mips_elf_final_gp (output_bfd
, symbol
, relocateable
, error_message
,
1362 if (ret
!= bfd_reloc_ok
)
1365 if (reloc_entry
->address
> input_section
->_cooked_size
)
1366 return bfd_reloc_outofrange
;
1368 if (bfd_is_com_section (symbol
->section
))
1371 relocation
= symbol
->value
;
1373 relocation
+= symbol
->section
->output_section
->vma
;
1374 relocation
+= symbol
->section
->output_offset
;
1376 /* Set val to the offset into the section or symbol. */
1377 val
= reloc_entry
->addend
;
1379 if (reloc_entry
->howto
->partial_inplace
)
1381 /* Pick up the mips16 extend instruction and the real instruction. */
1382 extend
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
1383 insn
= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1384 val
+= ((extend
& 0x1f) << 11) | (extend
& 0x7e0) | (insn
& 0x1f);
1387 _bfd_mips_elf_sign_extend(val
, 16);
1389 /* Adjust val for the final section location and GP value. If we
1390 are producing relocateable output, we don't want to do this for
1391 an external symbol. */
1393 || (symbol
->flags
& BSF_SECTION_SYM
) != 0)
1394 val
+= relocation
- gp
;
1396 if (reloc_entry
->howto
->partial_inplace
)
1399 (bfd_vma
) ((extend
& 0xf800)
1400 | ((val
>> 11) & 0x1f)
1402 (bfd_byte
*) data
+ reloc_entry
->address
);
1404 (bfd_vma
) ((insn
& 0xffe0)
1406 (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
1409 reloc_entry
->addend
= val
;
1412 reloc_entry
->address
+= input_section
->output_offset
;
1413 else if (((val
& ~0xffff) != ~0xffff) && ((val
& ~0xffff) != 0))
1414 return bfd_reloc_overflow
;
1416 return bfd_reloc_ok
;
1419 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1421 struct elf_reloc_map
{
1422 bfd_reloc_code_real_type bfd_val
;
1423 enum elf_mips_reloc_type elf_val
;
1426 static const struct elf_reloc_map mips_reloc_map
[] =
1428 { BFD_RELOC_NONE
, R_MIPS_NONE
},
1429 { BFD_RELOC_16
, R_MIPS_16
},
1430 { BFD_RELOC_32
, R_MIPS_32
},
1431 /* There is no BFD reloc for R_MIPS_REL32. */
1432 { BFD_RELOC_64
, R_MIPS_64
},
1433 { BFD_RELOC_MIPS_JMP
, R_MIPS_26
},
1434 { BFD_RELOC_HI16_S
, R_MIPS_HI16
},
1435 { BFD_RELOC_LO16
, R_MIPS_LO16
},
1436 { BFD_RELOC_GPREL16
, R_MIPS_GPREL16
},
1437 { BFD_RELOC_MIPS_LITERAL
, R_MIPS_LITERAL
},
1438 { BFD_RELOC_MIPS_GOT16
, R_MIPS_GOT16
},
1439 { BFD_RELOC_16_PCREL
, R_MIPS_PC16
},
1440 { BFD_RELOC_MIPS_CALL16
, R_MIPS_CALL16
},
1441 { BFD_RELOC_GPREL32
, R_MIPS_GPREL32
},
1442 { BFD_RELOC_MIPS_GOT_HI16
, R_MIPS_GOT_HI16
},
1443 { BFD_RELOC_MIPS_GOT_LO16
, R_MIPS_GOT_LO16
},
1444 { BFD_RELOC_MIPS_CALL_HI16
, R_MIPS_CALL_HI16
},
1445 { BFD_RELOC_MIPS_CALL_LO16
, R_MIPS_CALL_LO16
},
1446 { BFD_RELOC_MIPS_SUB
, R_MIPS_SUB
},
1447 { BFD_RELOC_MIPS_GOT_PAGE
, R_MIPS_GOT_PAGE
},
1448 { BFD_RELOC_MIPS_GOT_OFST
, R_MIPS_GOT_OFST
},
1449 { BFD_RELOC_MIPS_GOT_DISP
, R_MIPS_GOT_DISP
}
1452 /* Given a BFD reloc type, return a howto structure. */
1454 static reloc_howto_type
*
1455 bfd_elf32_bfd_reloc_type_lookup (abfd
, code
)
1457 bfd_reloc_code_real_type code
;
1460 reloc_howto_type
*howto_table
= elf_mips_howto_table_rel
;
1462 for (i
= 0; i
< sizeof (mips_reloc_map
) / sizeof (struct elf_reloc_map
);
1465 if (mips_reloc_map
[i
].bfd_val
== code
)
1466 return &howto_table
[(int) mips_reloc_map
[i
].elf_val
];
1472 bfd_set_error (bfd_error_bad_value
);
1475 case BFD_RELOC_CTOR
:
1476 /* We need to handle BFD_RELOC_CTOR specially.
1477 Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
1478 size of addresses of the ABI. */
1479 if ((elf_elfheader (abfd
)->e_flags
& (E_MIPS_ABI_O64
1480 | E_MIPS_ABI_EABI64
)) != 0)
1481 return &elf_mips_ctor64_howto
;
1483 return &howto_table
[(int) R_MIPS_32
];
1485 case BFD_RELOC_MIPS16_JMP
:
1486 return &elf_mips16_jump_howto
;
1487 case BFD_RELOC_MIPS16_GPREL
:
1488 return &elf_mips16_gprel_howto
;
1489 case BFD_RELOC_VTABLE_INHERIT
:
1490 return &elf_mips_gnu_vtinherit_howto
;
1491 case BFD_RELOC_VTABLE_ENTRY
:
1492 return &elf_mips_gnu_vtentry_howto
;
1493 case BFD_RELOC_PCREL_HI16_S
:
1494 return &elf_mips_gnu_rel_hi16
;
1495 case BFD_RELOC_PCREL_LO16
:
1496 return &elf_mips_gnu_rel_lo16
;
1497 case BFD_RELOC_16_PCREL_S2
:
1498 return &elf_mips_gnu_rel16_s2
;
1499 case BFD_RELOC_64_PCREL
:
1500 return &elf_mips_gnu_pcrel64
;
1501 case BFD_RELOC_32_PCREL
:
1502 return &elf_mips_gnu_pcrel32
;
1506 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1508 static reloc_howto_type
*
1509 mips_elf32_rtype_to_howto (r_type
, rela_p
)
1510 unsigned int r_type
;
1511 bfd_boolean rela_p ATTRIBUTE_UNUSED
;
1516 return &elf_mips16_jump_howto
;
1517 case R_MIPS16_GPREL
:
1518 return &elf_mips16_gprel_howto
;
1519 case R_MIPS_GNU_VTINHERIT
:
1520 return &elf_mips_gnu_vtinherit_howto
;
1521 case R_MIPS_GNU_VTENTRY
:
1522 return &elf_mips_gnu_vtentry_howto
;
1523 case R_MIPS_GNU_REL_HI16
:
1524 return &elf_mips_gnu_rel_hi16
;
1525 case R_MIPS_GNU_REL_LO16
:
1526 return &elf_mips_gnu_rel_lo16
;
1527 case R_MIPS_GNU_REL16_S2
:
1528 return &elf_mips_gnu_rel16_s2
;
1530 return &elf_mips_gnu_pcrel64
;
1532 return &elf_mips_gnu_pcrel32
;
1534 BFD_ASSERT (r_type
< (unsigned int) R_MIPS_max
);
1535 return &elf_mips_howto_table_rel
[r_type
];
1539 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1542 mips_info_to_howto_rel (abfd
, cache_ptr
, dst
)
1545 Elf_Internal_Rela
*dst
;
1547 unsigned int r_type
;
1549 r_type
= ELF32_R_TYPE (dst
->r_info
);
1550 cache_ptr
->howto
= mips_elf32_rtype_to_howto (r_type
, FALSE
);
1552 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1553 value for the object file. We get the addend now, rather than
1554 when we do the relocation, because the symbol manipulations done
1555 by the linker may cause us to lose track of the input BFD. */
1556 if (((*cache_ptr
->sym_ptr_ptr
)->flags
& BSF_SECTION_SYM
) != 0
1557 && (r_type
== (unsigned int) R_MIPS_GPREL16
1558 || r_type
== (unsigned int) R_MIPS_LITERAL
))
1559 cache_ptr
->addend
= elf_gp (abfd
);
1562 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
1565 mips_info_to_howto_rela (abfd
, cache_ptr
, dst
)
1568 Elf_Internal_Rela
*dst
;
1570 mips_info_to_howto_rel (abfd
, cache_ptr
, dst
);
1572 /* If we ever need to do any extra processing with dst->r_addend
1573 (the field omitted in an Elf_Internal_Rel) we can do it here. */
1576 /* Determine whether a symbol is global for the purposes of splitting
1577 the symbol table into global symbols and local symbols. At least
1578 on Irix 5, this split must be between section symbols and all other
1579 symbols. On most ELF targets the split is between static symbols
1580 and externally visible symbols. */
1583 mips_elf_sym_is_global (abfd
, sym
)
1584 bfd
*abfd ATTRIBUTE_UNUSED
;
1587 if (SGI_COMPAT (abfd
))
1588 return (sym
->flags
& BSF_SECTION_SYM
) == 0;
1590 return ((sym
->flags
& (BSF_GLOBAL
| BSF_WEAK
)) != 0
1591 || bfd_is_und_section (bfd_get_section (sym
))
1592 || bfd_is_com_section (bfd_get_section (sym
)));
1595 /* Set the right machine number for a MIPS ELF file. */
1598 mips_elf32_object_p (abfd
)
1603 /* Irix 5 and 6 are broken. Object file symbol tables are not always
1604 sorted correctly such that local symbols precede global symbols,
1605 and the sh_info field in the symbol table is not always right. */
1606 if (SGI_COMPAT (abfd
))
1607 elf_bad_symtab (abfd
) = TRUE
;
1609 if (ABI_N32_P (abfd
))
1612 mach
= _bfd_elf_mips_mach (elf_elfheader (abfd
)->e_flags
);
1613 bfd_default_set_arch_mach (abfd
, bfd_arch_mips
, mach
);
1618 /* MIPS ELF local labels start with '$', not 'L'. */
1621 mips_elf_is_local_label_name (abfd
, name
)
1628 /* On Irix 6, the labels go back to starting with '.', so we accept
1629 the generic ELF local label syntax as well. */
1630 return _bfd_elf_is_local_label_name (abfd
, name
);
1633 /* Support for core dump NOTE sections. */
1635 elf32_mips_grok_prstatus (abfd
, note
)
1637 Elf_Internal_Note
*note
;
1640 unsigned int raw_size
;
1642 switch (note
->descsz
)
1647 case 256: /* Linux/MIPS */
1649 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
1652 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
1661 /* Make a ".reg/999" section. */
1662 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
1663 raw_size
, note
->descpos
+ offset
);
1667 elf32_mips_grok_psinfo (abfd
, note
)
1669 Elf_Internal_Note
*note
;
1671 switch (note
->descsz
)
1676 case 128: /* Linux/MIPS elf_prpsinfo */
1677 elf_tdata (abfd
)->core_program
1678 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 32, 16);
1679 elf_tdata (abfd
)->core_command
1680 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 48, 80);
1683 /* Note that for some reason, a spurious space is tacked
1684 onto the end of the args in some (at least one anyway)
1685 implementations, so strip it off if it exists. */
1688 char *command
= elf_tdata (abfd
)->core_command
;
1689 int n
= strlen (command
);
1691 if (0 < n
&& command
[n
- 1] == ' ')
1692 command
[n
- 1] = '\0';
1698 /* Depending on the target vector we generate some version of Irix
1699 executables or "normal" MIPS ELF ABI executables. */
1700 static irix_compat_t
1701 elf32_mips_irix_compat (abfd
)
1704 if ((abfd
->xvec
== &bfd_elf32_bigmips_vec
)
1705 || (abfd
->xvec
== &bfd_elf32_littlemips_vec
))
1711 /* Given a data section and an in-memory embedded reloc section, store
1712 relocation information into the embedded reloc section which can be
1713 used at runtime to relocate the data section. This is called by the
1714 linker when the --embedded-relocs switch is used. This is called
1715 after the add_symbols entry point has been called for all the
1716 objects, and before the final_link entry point is called. */
1719 bfd_mips_elf32_create_embedded_relocs (abfd
, info
, datasec
, relsec
, errmsg
)
1721 struct bfd_link_info
*info
;
1726 Elf_Internal_Shdr
*symtab_hdr
;
1727 Elf_Internal_Sym
*isymbuf
= NULL
;
1728 Elf_Internal_Rela
*internal_relocs
= NULL
;
1729 Elf_Internal_Rela
*irel
, *irelend
;
1732 BFD_ASSERT (! info
->relocateable
);
1736 if (datasec
->reloc_count
== 0)
1739 /* Read this BFD's symbols if we haven't done so already, or get the cached
1740 copy if it exists. */
1741 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1742 if (symtab_hdr
->sh_info
!= 0)
1744 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1745 if (isymbuf
== NULL
)
1746 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
1747 symtab_hdr
->sh_info
, 0,
1749 if (isymbuf
== NULL
)
1753 /* Get a copy of the native relocations. */
1754 internal_relocs
= (_bfd_elf_link_read_relocs
1755 (abfd
, datasec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
1756 info
->keep_memory
));
1757 if (internal_relocs
== NULL
)
1760 relsec
->contents
= (bfd_byte
*) bfd_alloc (abfd
, datasec
->reloc_count
* 12);
1761 if (relsec
->contents
== NULL
)
1764 p
= relsec
->contents
;
1766 irelend
= internal_relocs
+ datasec
->reloc_count
;
1768 for (irel
= internal_relocs
; irel
< irelend
; irel
++, p
+= 12)
1770 asection
*targetsec
;
1772 /* We are going to write a four byte longword into the runtime
1773 reloc section. The longword will be the address in the data
1774 section which must be relocated. It is followed by the name
1775 of the target section NUL-padded or truncated to 8
1778 /* We can only relocate absolute longword relocs at run time. */
1779 if ((ELF32_R_TYPE (irel
->r_info
) != (int) R_MIPS_32
) &&
1780 (ELF32_R_TYPE (irel
->r_info
) != (int) R_MIPS_64
))
1782 *errmsg
= _("unsupported reloc type");
1783 bfd_set_error (bfd_error_bad_value
);
1786 /* Get the target section referred to by the reloc. */
1787 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1789 Elf_Internal_Sym
*isym
;
1791 /* A local symbol. */
1792 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1793 targetsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1798 struct elf_link_hash_entry
*h
;
1800 /* An external symbol. */
1801 indx
= ELF32_R_SYM (irel
->r_info
);
1802 h
= elf_sym_hashes (abfd
)[indx
];
1805 For some reason, in certain programs, the symbol will
1806 not be in the hash table. It seems to happen when you
1807 declare a static table of pointers to const external structures.
1808 In this case, the relocs are relative to data, not
1809 text, so just treating it like an undefined link
1810 should be sufficient. */
1811 BFD_ASSERT(h
!= NULL
);
1812 if (h
->root
.type
== bfd_link_hash_defined
1813 || h
->root
.type
== bfd_link_hash_defweak
)
1814 targetsec
= h
->root
.u
.def
.section
;
1819 Set the low bit of the relocation offset if it's a MIPS64 reloc.
1820 Relocations will always be on (at least) 32-bit boundaries. */
1822 bfd_put_32 (abfd
, ((irel
->r_offset
+ datasec
->output_offset
) +
1823 ((ELF32_R_TYPE (irel
->r_info
) == (int) R_MIPS_64
) ? 1 : 0)),
1825 memset (p
+ 4, 0, 8);
1826 if (targetsec
!= NULL
)
1827 strncpy (p
+ 4, targetsec
->output_section
->name
, 8);
1830 if (internal_relocs
!= NULL
1831 && elf_section_data (datasec
)->relocs
!= internal_relocs
)
1832 free (internal_relocs
);
1834 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1839 if (internal_relocs
!= NULL
1840 && elf_section_data (datasec
)->relocs
!= internal_relocs
)
1841 free (internal_relocs
);
1843 && symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
1848 /* ECOFF swapping routines. These are used when dealing with the
1849 .mdebug section, which is in the ECOFF debugging format. */
1850 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap
= {
1851 /* Symbol table magic number. */
1853 /* Alignment of debugging information. E.g., 4. */
1855 /* Sizes of external symbolic information. */
1856 sizeof (struct hdr_ext
),
1857 sizeof (struct dnr_ext
),
1858 sizeof (struct pdr_ext
),
1859 sizeof (struct sym_ext
),
1860 sizeof (struct opt_ext
),
1861 sizeof (struct fdr_ext
),
1862 sizeof (struct rfd_ext
),
1863 sizeof (struct ext_ext
),
1864 /* Functions to swap in external symbolic data. */
1873 _bfd_ecoff_swap_tir_in
,
1874 _bfd_ecoff_swap_rndx_in
,
1875 /* Functions to swap out external symbolic data. */
1884 _bfd_ecoff_swap_tir_out
,
1885 _bfd_ecoff_swap_rndx_out
,
1886 /* Function to read in symbolic data. */
1887 _bfd_mips_elf_read_ecoff_info
1890 #define ELF_ARCH bfd_arch_mips
1891 #define ELF_MACHINE_CODE EM_MIPS
1893 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
1894 a value of 0x1000, and we are compatible. */
1895 #define ELF_MAXPAGESIZE 0x1000
1897 #define elf_backend_collect TRUE
1898 #define elf_backend_type_change_ok TRUE
1899 #define elf_backend_can_gc_sections TRUE
1900 #define elf_info_to_howto mips_info_to_howto_rela
1901 #define elf_info_to_howto_rel mips_info_to_howto_rel
1902 #define elf_backend_sym_is_global mips_elf_sym_is_global
1903 #define elf_backend_object_p mips_elf32_object_p
1904 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
1905 #define elf_backend_section_processing _bfd_mips_elf_section_processing
1906 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
1907 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
1908 #define elf_backend_section_from_bfd_section \
1909 _bfd_mips_elf_section_from_bfd_section
1910 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
1911 #define elf_backend_link_output_symbol_hook \
1912 _bfd_mips_elf_link_output_symbol_hook
1913 #define elf_backend_create_dynamic_sections \
1914 _bfd_mips_elf_create_dynamic_sections
1915 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
1916 #define elf_backend_adjust_dynamic_symbol \
1917 _bfd_mips_elf_adjust_dynamic_symbol
1918 #define elf_backend_always_size_sections \
1919 _bfd_mips_elf_always_size_sections
1920 #define elf_backend_size_dynamic_sections \
1921 _bfd_mips_elf_size_dynamic_sections
1922 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
1923 #define elf_backend_finish_dynamic_symbol \
1924 _bfd_mips_elf_finish_dynamic_symbol
1925 #define elf_backend_finish_dynamic_sections \
1926 _bfd_mips_elf_finish_dynamic_sections
1927 #define elf_backend_final_write_processing \
1928 _bfd_mips_elf_final_write_processing
1929 #define elf_backend_additional_program_headers \
1930 _bfd_mips_elf_additional_program_headers
1931 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
1932 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
1933 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
1934 #define elf_backend_copy_indirect_symbol \
1935 _bfd_mips_elf_copy_indirect_symbol
1936 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
1937 #define elf_backend_grok_prstatus elf32_mips_grok_prstatus
1938 #define elf_backend_grok_psinfo elf32_mips_grok_psinfo
1939 #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
1941 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
1942 #define elf_backend_plt_header_size 0
1943 #define elf_backend_may_use_rel_p 1
1944 #define elf_backend_may_use_rela_p 0
1945 #define elf_backend_default_use_rela_p 0
1946 #define elf_backend_sign_extend_vma TRUE
1948 #define elf_backend_discard_info _bfd_mips_elf_discard_info
1949 #define elf_backend_ignore_discarded_relocs \
1950 _bfd_mips_elf_ignore_discarded_relocs
1951 #define elf_backend_mips_irix_compat elf32_mips_irix_compat
1952 #define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
1953 #define bfd_elf32_bfd_is_local_label_name \
1954 mips_elf_is_local_label_name
1955 #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
1956 #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
1957 #define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
1958 #define bfd_elf32_bfd_get_relocated_section_contents \
1959 _bfd_elf_mips_get_relocated_section_contents
1960 #define bfd_elf32_bfd_link_hash_table_create \
1961 _bfd_mips_elf_link_hash_table_create
1962 #define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
1963 #define bfd_elf32_bfd_merge_private_bfd_data \
1964 _bfd_mips_elf_merge_private_bfd_data
1965 #define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
1966 #define bfd_elf32_bfd_print_private_bfd_data \
1967 _bfd_mips_elf_print_private_bfd_data
1969 /* Support for SGI-ish mips targets. */
1970 #define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec
1971 #define TARGET_LITTLE_NAME "elf32-littlemips"
1972 #define TARGET_BIG_SYM bfd_elf32_bigmips_vec
1973 #define TARGET_BIG_NAME "elf32-bigmips"
1975 #include "elf32-target.h"
1977 /* Support for traditional mips targets. */
1978 #define INCLUDED_TARGET_FILE /* More a type of flag. */
1980 #undef TARGET_LITTLE_SYM
1981 #undef TARGET_LITTLE_NAME
1982 #undef TARGET_BIG_SYM
1983 #undef TARGET_BIG_NAME
1985 #define TARGET_LITTLE_SYM bfd_elf32_tradlittlemips_vec
1986 #define TARGET_LITTLE_NAME "elf32-tradlittlemips"
1987 #define TARGET_BIG_SYM bfd_elf32_tradbigmips_vec
1988 #define TARGET_BIG_NAME "elf32-tradbigmips"
1990 /* Include the target file again for this target. */
1991 #include "elf32-target.h"