* config/tc-mn10200.c (md_parse_option <c, arg>): Add ATTRIBUTE_UNUSED.
[binutils.git] / bfd / elf64-mips.c
blob50fcfbabf19696152657b5262a5e5c8fc040c269
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Ian Lance Taylor, Cygnus Support
5 Linker support added by Mark Mitchell, CodeSourcery, LLC.
6 <mark@codesourcery.com>
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 /* This file supports the 64-bit MIPS ELF ABI.
26 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
27 overrides the usual ELF reloc handling, and handles reading and
28 writing the relocations here. */
30 /* TODO: Many things are unsupported, even if there is some code for it
31 . (which was mostly stolen from elf32-mips.c and slightly adapted).
33 . - Relocation handling for REL relocs is wrong in many cases and
34 . generally untested.
35 . - Relocation handling for RELA relocs related to GOT support are
36 . also likely to be wrong.
37 . - Support for MIPS16 is untested.
38 . - Combined relocs with RSS_* entries are unsupported.
39 . - The whole GOT handling for NewABI is missing, some parts of
40 . the OldABI version is still lying around and should be removed.
43 #include "bfd.h"
44 #include "sysdep.h"
45 #include "libbfd.h"
46 #include "aout/ar.h"
47 #include "bfdlink.h"
48 #include "genlink.h"
49 #include "elf-bfd.h"
50 #include "elfxx-mips.h"
51 #include "elf/mips.h"
53 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
54 use ECOFF. However, we support it anyhow for an easier changeover. */
55 #include "coff/sym.h"
56 #include "coff/symconst.h"
57 #include "coff/internal.h"
58 #include "coff/ecoff.h"
59 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
60 #include "coff/alpha.h"
61 #define ECOFF_SIGNED_64
62 #include "ecoffswap.h"
64 static void mips_elf64_swap_reloc_in
65 PARAMS ((bfd *, const Elf64_Mips_External_Rel *,
66 Elf64_Mips_Internal_Rela *));
67 static void mips_elf64_swap_reloca_in
68 PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
69 Elf64_Mips_Internal_Rela *));
70 static void mips_elf64_swap_reloc_out
71 PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
72 Elf64_Mips_External_Rel *));
73 static void mips_elf64_swap_reloca_out
74 PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
75 Elf64_Mips_External_Rela *));
76 static void mips_elf64_be_swap_reloc_in
77 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
78 static void mips_elf64_be_swap_reloc_out
79 PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
80 static void mips_elf64_be_swap_reloca_in
81 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
82 static void mips_elf64_be_swap_reloca_out
83 PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
84 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
85 PARAMS ((bfd *, bfd_reloc_code_real_type));
86 static reloc_howto_type *mips_elf64_rtype_to_howto
87 PARAMS ((unsigned int, bfd_boolean));
88 static void mips_elf64_info_to_howto_rel
89 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
90 static void mips_elf64_info_to_howto_rela
91 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
92 static long mips_elf64_get_reloc_upper_bound
93 PARAMS ((bfd *, asection *));
94 static bfd_boolean mips_elf64_slurp_one_reloc_table
95 PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *));
96 static bfd_boolean mips_elf64_slurp_reloc_table
97 PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
98 static void mips_elf64_write_relocs
99 PARAMS ((bfd *, asection *, PTR));
100 static void mips_elf64_write_rel
101 PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR));
102 static void mips_elf64_write_rela
103 PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR));
104 static bfd_reloc_status_type mips_elf64_hi16_reloc
105 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
106 static bfd_reloc_status_type mips_elf64_gprel16_reloc
107 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
108 static bfd_reloc_status_type mips_elf64_literal_reloc
109 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
110 static bfd_reloc_status_type mips_elf64_gprel32_reloc
111 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
112 static bfd_reloc_status_type mips_elf64_shift6_reloc
113 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
114 static bfd_reloc_status_type mips_elf64_got16_reloc
115 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
116 static bfd_reloc_status_type mips16_jump_reloc
117 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
118 static bfd_reloc_status_type mips16_gprel_reloc
119 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
120 static bfd_boolean mips_elf64_assign_gp
121 PARAMS ((bfd *, bfd_vma *));
122 static bfd_reloc_status_type mips_elf64_final_gp
123 PARAMS ((bfd *, asymbol *, bfd_boolean, char **, bfd_vma *));
124 static bfd_boolean mips_elf64_object_p
125 PARAMS ((bfd *));
126 static irix_compat_t elf64_mips_irix_compat
127 PARAMS ((bfd *));
128 static bfd_boolean elf64_mips_grok_prstatus
129 PARAMS ((bfd *, Elf_Internal_Note *));
130 static bfd_boolean elf64_mips_grok_psinfo
131 PARAMS ((bfd *, Elf_Internal_Note *));
133 extern const bfd_target bfd_elf64_bigmips_vec;
134 extern const bfd_target bfd_elf64_littlemips_vec;
136 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
137 from smaller values. Start with zero, widen, *then* decrement. */
138 #define MINUS_ONE (((bfd_vma)0) - 1)
140 /* The number of local .got entries we reserve. */
141 #define MIPS_RESERVED_GOTNO (2)
143 /* The relocation table used for SHT_REL sections. */
145 static reloc_howto_type mips_elf64_howto_table_rel[] =
147 /* No relocation. */
148 HOWTO (R_MIPS_NONE, /* type */
149 0, /* rightshift */
150 0, /* size (0 = byte, 1 = short, 2 = long) */
151 0, /* bitsize */
152 FALSE, /* pc_relative */
153 0, /* bitpos */
154 complain_overflow_dont, /* complain_on_overflow */
155 bfd_elf_generic_reloc, /* special_function */
156 "R_MIPS_NONE", /* name */
157 FALSE, /* partial_inplace */
158 0, /* src_mask */
159 0, /* dst_mask */
160 FALSE), /* pcrel_offset */
162 /* 16 bit relocation. */
163 HOWTO (R_MIPS_16, /* type */
164 0, /* rightshift */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
166 16, /* bitsize */
167 FALSE, /* pc_relative */
168 0, /* bitpos */
169 complain_overflow_signed, /* complain_on_overflow */
170 bfd_elf_generic_reloc, /* special_function */
171 "R_MIPS_16", /* name */
172 TRUE, /* partial_inplace */
173 0x0000ffff, /* src_mask */
174 0x0000ffff, /* dst_mask */
175 FALSE), /* pcrel_offset */
177 /* 32 bit relocation. */
178 HOWTO (R_MIPS_32, /* type */
179 0, /* rightshift */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
181 32, /* bitsize */
182 FALSE, /* pc_relative */
183 0, /* bitpos */
184 complain_overflow_dont, /* complain_on_overflow */
185 bfd_elf_generic_reloc, /* special_function */
186 "R_MIPS_32", /* name */
187 TRUE, /* partial_inplace */
188 0xffffffff, /* src_mask */
189 0xffffffff, /* dst_mask */
190 FALSE), /* pcrel_offset */
192 /* 32 bit symbol relative relocation. */
193 HOWTO (R_MIPS_REL32, /* type */
194 0, /* rightshift */
195 2, /* size (0 = byte, 1 = short, 2 = long) */
196 32, /* bitsize */
197 FALSE, /* pc_relative */
198 0, /* bitpos */
199 complain_overflow_dont, /* complain_on_overflow */
200 bfd_elf_generic_reloc, /* special_function */
201 "R_MIPS_REL32", /* name */
202 TRUE, /* partial_inplace */
203 0xffffffff, /* src_mask */
204 0xffffffff, /* dst_mask */
205 FALSE), /* pcrel_offset */
207 /* 26 bit jump address. */
208 HOWTO (R_MIPS_26, /* type */
209 2, /* rightshift */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
211 26, /* bitsize */
212 FALSE, /* pc_relative */
213 0, /* bitpos */
214 complain_overflow_dont, /* complain_on_overflow */
215 /* This needs complex overflow
216 detection, because the upper 36
217 bits must match the PC + 4. */
218 bfd_elf_generic_reloc, /* special_function */
219 "R_MIPS_26", /* name */
220 TRUE, /* partial_inplace */
221 0x03ffffff, /* src_mask */
222 0x03ffffff, /* dst_mask */
223 FALSE), /* pcrel_offset */
225 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
226 However, the native IRIX6 tools use them, so we try our best. */
228 /* High 16 bits of symbol value. */
229 HOWTO (R_MIPS_HI16, /* type */
230 0, /* rightshift */
231 2, /* size (0 = byte, 1 = short, 2 = long) */
232 16, /* bitsize */
233 FALSE, /* pc_relative */
234 0, /* bitpos */
235 complain_overflow_dont, /* complain_on_overflow */
236 mips_elf64_hi16_reloc, /* special_function */
237 "R_MIPS_HI16", /* name */
238 TRUE, /* partial_inplace */
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
241 FALSE), /* pcrel_offset */
243 /* Low 16 bits of symbol value. */
244 HOWTO (R_MIPS_LO16, /* type */
245 0, /* rightshift */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
247 16, /* bitsize */
248 FALSE, /* pc_relative */
249 0, /* bitpos */
250 complain_overflow_dont, /* complain_on_overflow */
251 bfd_elf_generic_reloc, /* special_function */
252 "R_MIPS_LO16", /* name */
253 TRUE, /* partial_inplace */
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
256 FALSE), /* pcrel_offset */
258 /* GP relative reference. */
259 HOWTO (R_MIPS_GPREL16, /* type */
260 0, /* rightshift */
261 2, /* size (0 = byte, 1 = short, 2 = long) */
262 16, /* bitsize */
263 FALSE, /* pc_relative */
264 0, /* bitpos */
265 complain_overflow_signed, /* complain_on_overflow */
266 mips_elf64_gprel16_reloc, /* special_function */
267 "R_MIPS_GPREL16", /* name */
268 TRUE, /* partial_inplace */
269 0x0000ffff, /* src_mask */
270 0x0000ffff, /* dst_mask */
271 FALSE), /* pcrel_offset */
273 /* Reference to literal section. */
274 HOWTO (R_MIPS_LITERAL, /* type */
275 0, /* rightshift */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
277 16, /* bitsize */
278 FALSE, /* pc_relative */
279 0, /* bitpos */
280 complain_overflow_signed, /* complain_on_overflow */
281 mips_elf64_literal_reloc, /* special_function */
282 "R_MIPS_LITERAL", /* name */
283 TRUE, /* partial_inplace */
284 0x0000ffff, /* src_mask */
285 0x0000ffff, /* dst_mask */
286 FALSE), /* pcrel_offset */
288 /* Reference to global offset table. */
289 HOWTO (R_MIPS_GOT16, /* type */
290 0, /* rightshift */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
292 16, /* bitsize */
293 FALSE, /* pc_relative */
294 0, /* bitpos */
295 complain_overflow_signed, /* complain_on_overflow */
296 mips_elf64_got16_reloc, /* special_function */
297 "R_MIPS_GOT16", /* name */
298 TRUE, /* partial_inplace */
299 0x0000ffff, /* src_mask */
300 0x0000ffff, /* dst_mask */
301 FALSE), /* pcrel_offset */
303 /* 16 bit PC relative reference. */
304 HOWTO (R_MIPS_PC16, /* type */
305 0, /* rightshift */
306 2, /* size (0 = byte, 1 = short, 2 = long) */
307 16, /* bitsize */
308 TRUE, /* pc_relative */
309 0, /* bitpos */
310 complain_overflow_signed, /* complain_on_overflow */
311 bfd_elf_generic_reloc, /* special_function */
312 "R_MIPS_PC16", /* name */
313 TRUE, /* partial_inplace */
314 0x0000ffff, /* src_mask */
315 0x0000ffff, /* dst_mask */
316 TRUE), /* pcrel_offset */
318 /* 16 bit call through global offset table. */
319 HOWTO (R_MIPS_CALL16, /* type */
320 0, /* rightshift */
321 2, /* size (0 = byte, 1 = short, 2 = long) */
322 16, /* bitsize */
323 FALSE, /* pc_relative */
324 0, /* bitpos */
325 complain_overflow_signed, /* complain_on_overflow */
326 bfd_elf_generic_reloc, /* special_function */
327 "R_MIPS_CALL16", /* name */
328 TRUE, /* partial_inplace */
329 0x0000ffff, /* src_mask */
330 0x0000ffff, /* dst_mask */
331 FALSE), /* pcrel_offset */
333 /* 32 bit GP relative reference. */
334 HOWTO (R_MIPS_GPREL32, /* type */
335 0, /* rightshift */
336 2, /* size (0 = byte, 1 = short, 2 = long) */
337 32, /* bitsize */
338 FALSE, /* pc_relative */
339 0, /* bitpos */
340 complain_overflow_dont, /* complain_on_overflow */
341 mips_elf64_gprel32_reloc, /* special_function */
342 "R_MIPS_GPREL32", /* name */
343 TRUE, /* partial_inplace */
344 0xffffffff, /* src_mask */
345 0xffffffff, /* dst_mask */
346 FALSE), /* pcrel_offset */
348 EMPTY_HOWTO (13),
349 EMPTY_HOWTO (14),
350 EMPTY_HOWTO (15),
352 /* A 5 bit shift field. */
353 HOWTO (R_MIPS_SHIFT5, /* type */
354 0, /* rightshift */
355 2, /* size (0 = byte, 1 = short, 2 = long) */
356 5, /* bitsize */
357 FALSE, /* pc_relative */
358 6, /* bitpos */
359 complain_overflow_bitfield, /* complain_on_overflow */
360 bfd_elf_generic_reloc, /* special_function */
361 "R_MIPS_SHIFT5", /* name */
362 TRUE, /* partial_inplace */
363 0x000007c0, /* src_mask */
364 0x000007c0, /* dst_mask */
365 FALSE), /* pcrel_offset */
367 /* A 6 bit shift field. */
368 HOWTO (R_MIPS_SHIFT6, /* type */
369 0, /* rightshift */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
371 6, /* bitsize */
372 FALSE, /* pc_relative */
373 6, /* bitpos */
374 complain_overflow_bitfield, /* complain_on_overflow */
375 mips_elf64_shift6_reloc, /* special_function */
376 "R_MIPS_SHIFT6", /* name */
377 TRUE, /* partial_inplace */
378 0x000007c4, /* src_mask */
379 0x000007c4, /* dst_mask */
380 FALSE), /* pcrel_offset */
382 /* 64 bit relocation. */
383 HOWTO (R_MIPS_64, /* type */
384 0, /* rightshift */
385 4, /* size (0 = byte, 1 = short, 2 = long) */
386 64, /* bitsize */
387 FALSE, /* pc_relative */
388 0, /* bitpos */
389 complain_overflow_dont, /* complain_on_overflow */
390 bfd_elf_generic_reloc, /* special_function */
391 "R_MIPS_64", /* name */
392 TRUE, /* partial_inplace */
393 MINUS_ONE, /* src_mask */
394 MINUS_ONE, /* dst_mask */
395 FALSE), /* pcrel_offset */
397 /* Displacement in the global offset table. */
398 HOWTO (R_MIPS_GOT_DISP, /* type */
399 0, /* rightshift */
400 2, /* size (0 = byte, 1 = short, 2 = long) */
401 16, /* bitsize */
402 FALSE, /* pc_relative */
403 0, /* bitpos */
404 complain_overflow_signed, /* complain_on_overflow */
405 bfd_elf_generic_reloc, /* special_function */
406 "R_MIPS_GOT_DISP", /* name */
407 TRUE, /* partial_inplace */
408 0x0000ffff, /* src_mask */
409 0x0000ffff, /* dst_mask */
410 FALSE), /* pcrel_offset */
412 /* Displacement to page pointer in the global offset table. */
413 HOWTO (R_MIPS_GOT_PAGE, /* type */
414 0, /* rightshift */
415 2, /* size (0 = byte, 1 = short, 2 = long) */
416 16, /* bitsize */
417 FALSE, /* pc_relative */
418 0, /* bitpos */
419 complain_overflow_signed, /* complain_on_overflow */
420 bfd_elf_generic_reloc, /* special_function */
421 "R_MIPS_GOT_PAGE", /* name */
422 TRUE, /* partial_inplace */
423 0x0000ffff, /* src_mask */
424 0x0000ffff, /* dst_mask */
425 FALSE), /* pcrel_offset */
427 /* Offset from page pointer in the global offset table. */
428 HOWTO (R_MIPS_GOT_OFST, /* type */
429 0, /* rightshift */
430 2, /* size (0 = byte, 1 = short, 2 = long) */
431 16, /* bitsize */
432 FALSE, /* pc_relative */
433 0, /* bitpos */
434 complain_overflow_signed, /* complain_on_overflow */
435 bfd_elf_generic_reloc, /* special_function */
436 "R_MIPS_GOT_OFST", /* name */
437 TRUE, /* partial_inplace */
438 0x0000ffff, /* src_mask */
439 0x0000ffff, /* dst_mask */
440 FALSE), /* pcrel_offset */
442 /* High 16 bits of displacement in global offset table. */
443 HOWTO (R_MIPS_GOT_HI16, /* type */
444 0, /* rightshift */
445 2, /* size (0 = byte, 1 = short, 2 = long) */
446 16, /* bitsize */
447 FALSE, /* pc_relative */
448 0, /* bitpos */
449 complain_overflow_dont, /* complain_on_overflow */
450 bfd_elf_generic_reloc, /* special_function */
451 "R_MIPS_GOT_HI16", /* name */
452 TRUE, /* partial_inplace */
453 0x0000ffff, /* src_mask */
454 0x0000ffff, /* dst_mask */
455 FALSE), /* pcrel_offset */
457 /* Low 16 bits of displacement in global offset table. */
458 HOWTO (R_MIPS_GOT_LO16, /* type */
459 0, /* rightshift */
460 2, /* size (0 = byte, 1 = short, 2 = long) */
461 16, /* bitsize */
462 FALSE, /* pc_relative */
463 0, /* bitpos */
464 complain_overflow_dont, /* complain_on_overflow */
465 bfd_elf_generic_reloc, /* special_function */
466 "R_MIPS_GOT_LO16", /* name */
467 TRUE, /* partial_inplace */
468 0x0000ffff, /* src_mask */
469 0x0000ffff, /* dst_mask */
470 FALSE), /* pcrel_offset */
472 /* 64 bit substraction. */
473 HOWTO (R_MIPS_SUB, /* type */
474 0, /* rightshift */
475 4, /* size (0 = byte, 1 = short, 2 = long) */
476 64, /* bitsize */
477 FALSE, /* pc_relative */
478 0, /* bitpos */
479 complain_overflow_dont, /* complain_on_overflow */
480 bfd_elf_generic_reloc, /* special_function */
481 "R_MIPS_SUB", /* name */
482 TRUE, /* partial_inplace */
483 MINUS_ONE, /* src_mask */
484 MINUS_ONE, /* dst_mask */
485 FALSE), /* pcrel_offset */
487 /* Insert the addend as an instruction. */
488 /* FIXME: Not handled correctly. */
489 HOWTO (R_MIPS_INSERT_A, /* type */
490 0, /* rightshift */
491 2, /* size (0 = byte, 1 = short, 2 = long) */
492 32, /* bitsize */
493 FALSE, /* pc_relative */
494 0, /* bitpos */
495 complain_overflow_dont, /* complain_on_overflow */
496 bfd_elf_generic_reloc, /* special_function */
497 "R_MIPS_INSERT_A", /* name */
498 TRUE, /* partial_inplace */
499 0xffffffff, /* src_mask */
500 0xffffffff, /* dst_mask */
501 FALSE), /* pcrel_offset */
503 /* Insert the addend as an instruction, and change all relocations
504 to refer to the old instruction at the address. */
505 /* FIXME: Not handled correctly. */
506 HOWTO (R_MIPS_INSERT_B, /* type */
507 0, /* rightshift */
508 2, /* size (0 = byte, 1 = short, 2 = long) */
509 32, /* bitsize */
510 FALSE, /* pc_relative */
511 0, /* bitpos */
512 complain_overflow_dont, /* complain_on_overflow */
513 bfd_elf_generic_reloc, /* special_function */
514 "R_MIPS_INSERT_B", /* name */
515 TRUE, /* partial_inplace */
516 0xffffffff, /* src_mask */
517 0xffffffff, /* dst_mask */
518 FALSE), /* pcrel_offset */
520 /* Delete a 32 bit instruction. */
521 /* FIXME: Not handled correctly. */
522 HOWTO (R_MIPS_DELETE, /* type */
523 0, /* rightshift */
524 2, /* size (0 = byte, 1 = short, 2 = long) */
525 32, /* bitsize */
526 FALSE, /* pc_relative */
527 0, /* bitpos */
528 complain_overflow_dont, /* complain_on_overflow */
529 bfd_elf_generic_reloc, /* special_function */
530 "R_MIPS_DELETE", /* name */
531 TRUE, /* partial_inplace */
532 0xffffffff, /* src_mask */
533 0xffffffff, /* dst_mask */
534 FALSE), /* pcrel_offset */
536 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
537 We don't, because
538 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
539 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
540 fallable heuristics.
541 b) No other NewABI toolchain actually emits such relocations. */
542 EMPTY_HOWTO (R_MIPS_HIGHER),
543 EMPTY_HOWTO (R_MIPS_HIGHEST),
545 /* High 16 bits of displacement in global offset table. */
546 HOWTO (R_MIPS_CALL_HI16, /* type */
547 0, /* rightshift */
548 2, /* size (0 = byte, 1 = short, 2 = long) */
549 16, /* bitsize */
550 FALSE, /* pc_relative */
551 0, /* bitpos */
552 complain_overflow_dont, /* complain_on_overflow */
553 bfd_elf_generic_reloc, /* special_function */
554 "R_MIPS_CALL_HI16", /* name */
555 TRUE, /* partial_inplace */
556 0x0000ffff, /* src_mask */
557 0x0000ffff, /* dst_mask */
558 FALSE), /* pcrel_offset */
560 /* Low 16 bits of displacement in global offset table. */
561 HOWTO (R_MIPS_CALL_LO16, /* type */
562 0, /* rightshift */
563 2, /* size (0 = byte, 1 = short, 2 = long) */
564 16, /* bitsize */
565 FALSE, /* pc_relative */
566 0, /* bitpos */
567 complain_overflow_dont, /* complain_on_overflow */
568 bfd_elf_generic_reloc, /* special_function */
569 "R_MIPS_CALL_LO16", /* name */
570 TRUE, /* partial_inplace */
571 0x0000ffff, /* src_mask */
572 0x0000ffff, /* dst_mask */
573 FALSE), /* pcrel_offset */
575 /* Section displacement, used by an associated event location section. */
576 HOWTO (R_MIPS_SCN_DISP, /* type */
577 0, /* rightshift */
578 2, /* size (0 = byte, 1 = short, 2 = long) */
579 32, /* bitsize */
580 FALSE, /* pc_relative */
581 0, /* bitpos */
582 complain_overflow_dont, /* complain_on_overflow */
583 bfd_elf_generic_reloc, /* special_function */
584 "R_MIPS_SCN_DISP", /* name */
585 TRUE, /* partial_inplace */
586 0xffffffff, /* src_mask */
587 0xffffffff, /* dst_mask */
588 FALSE), /* pcrel_offset */
590 HOWTO (R_MIPS_REL16, /* type */
591 0, /* rightshift */
592 1, /* size (0 = byte, 1 = short, 2 = long) */
593 16, /* bitsize */
594 FALSE, /* pc_relative */
595 0, /* bitpos */
596 complain_overflow_signed, /* complain_on_overflow */
597 bfd_elf_generic_reloc, /* special_function */
598 "R_MIPS_REL16", /* name */
599 TRUE, /* partial_inplace */
600 0xffff, /* src_mask */
601 0xffff, /* dst_mask */
602 FALSE), /* pcrel_offset */
604 /* These two are obsolete. */
605 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
606 EMPTY_HOWTO (R_MIPS_PJUMP),
608 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
609 It must be used for multigot GOT's (and only there). */
610 HOWTO (R_MIPS_RELGOT, /* type */
611 0, /* rightshift */
612 2, /* size (0 = byte, 1 = short, 2 = long) */
613 32, /* bitsize */
614 FALSE, /* pc_relative */
615 0, /* bitpos */
616 complain_overflow_dont, /* complain_on_overflow */
617 bfd_elf_generic_reloc, /* special_function */
618 "R_MIPS_RELGOT", /* name */
619 TRUE, /* partial_inplace */
620 0xffffffff, /* src_mask */
621 0xffffffff, /* dst_mask */
622 FALSE), /* pcrel_offset */
624 /* Protected jump conversion. This is an optimization hint. No
625 relocation is required for correctness. */
626 HOWTO (R_MIPS_JALR, /* type */
627 0, /* rightshift */
628 2, /* size (0 = byte, 1 = short, 2 = long) */
629 32, /* bitsize */
630 FALSE, /* pc_relative */
631 0, /* bitpos */
632 complain_overflow_dont, /* complain_on_overflow */
633 bfd_elf_generic_reloc, /* special_function */
634 "R_MIPS_JALR", /* name */
635 FALSE, /* partial_inplace */
636 0, /* src_mask */
637 0x00000000, /* dst_mask */
638 FALSE), /* pcrel_offset */
641 /* The relocation table used for SHT_RELA sections. */
643 static reloc_howto_type mips_elf64_howto_table_rela[] =
645 /* No relocation. */
646 HOWTO (R_MIPS_NONE, /* type */
647 0, /* rightshift */
648 0, /* size (0 = byte, 1 = short, 2 = long) */
649 0, /* bitsize */
650 FALSE, /* pc_relative */
651 0, /* bitpos */
652 complain_overflow_dont, /* complain_on_overflow */
653 bfd_elf_generic_reloc, /* special_function */
654 "R_MIPS_NONE", /* name */
655 FALSE, /* partial_inplace */
656 0, /* src_mask */
657 0, /* dst_mask */
658 FALSE), /* pcrel_offset */
660 /* 16 bit relocation. */
661 HOWTO (R_MIPS_16, /* type */
662 0, /* rightshift */
663 2, /* size (0 = byte, 1 = short, 2 = long) */
664 16, /* bitsize */
665 FALSE, /* pc_relative */
666 0, /* bitpos */
667 complain_overflow_signed, /* complain_on_overflow */
668 bfd_elf_generic_reloc, /* special_function */
669 "R_MIPS_16", /* name */
670 FALSE, /* partial_inplace */
671 0, /* src_mask */
672 0x0000ffff, /* dst_mask */
673 FALSE), /* pcrel_offset */
675 /* 32 bit relocation. */
676 HOWTO (R_MIPS_32, /* type */
677 0, /* rightshift */
678 2, /* size (0 = byte, 1 = short, 2 = long) */
679 32, /* bitsize */
680 FALSE, /* pc_relative */
681 0, /* bitpos */
682 complain_overflow_dont, /* complain_on_overflow */
683 bfd_elf_generic_reloc, /* special_function */
684 "R_MIPS_32", /* name */
685 FALSE, /* partial_inplace */
686 0, /* src_mask */
687 0xffffffff, /* dst_mask */
688 FALSE), /* pcrel_offset */
690 /* 32 bit symbol relative relocation. */
691 HOWTO (R_MIPS_REL32, /* type */
692 0, /* rightshift */
693 2, /* size (0 = byte, 1 = short, 2 = long) */
694 32, /* bitsize */
695 FALSE, /* pc_relative */
696 0, /* bitpos */
697 complain_overflow_dont, /* complain_on_overflow */
698 bfd_elf_generic_reloc, /* special_function */
699 "R_MIPS_REL32", /* name */
700 FALSE, /* partial_inplace */
701 0, /* src_mask */
702 0xffffffff, /* dst_mask */
703 FALSE), /* pcrel_offset */
705 /* 26 bit jump address. */
706 HOWTO (R_MIPS_26, /* type */
707 2, /* rightshift */
708 2, /* size (0 = byte, 1 = short, 2 = long) */
709 26, /* bitsize */
710 FALSE, /* pc_relative */
711 0, /* bitpos */
712 complain_overflow_dont, /* complain_on_overflow */
713 /* This needs complex overflow
714 detection, because the upper 36
715 bits must match the PC + 4. */
716 bfd_elf_generic_reloc, /* special_function */
717 "R_MIPS_26", /* name */
718 FALSE, /* partial_inplace */
719 0, /* src_mask */
720 0x03ffffff, /* dst_mask */
721 FALSE), /* pcrel_offset */
723 /* High 16 bits of symbol value. */
724 HOWTO (R_MIPS_HI16, /* type */
725 0, /* rightshift */
726 2, /* size (0 = byte, 1 = short, 2 = long) */
727 16, /* bitsize */
728 FALSE, /* pc_relative */
729 0, /* bitpos */
730 complain_overflow_dont, /* complain_on_overflow */
731 bfd_elf_generic_reloc, /* special_function */
732 "R_MIPS_HI16", /* name */
733 FALSE, /* partial_inplace */
734 0, /* src_mask */
735 0x0000ffff, /* dst_mask */
736 FALSE), /* pcrel_offset */
738 /* Low 16 bits of symbol value. */
739 HOWTO (R_MIPS_LO16, /* type */
740 0, /* rightshift */
741 2, /* size (0 = byte, 1 = short, 2 = long) */
742 16, /* bitsize */
743 FALSE, /* pc_relative */
744 0, /* bitpos */
745 complain_overflow_dont, /* complain_on_overflow */
746 bfd_elf_generic_reloc, /* special_function */
747 "R_MIPS_LO16", /* name */
748 FALSE, /* partial_inplace */
749 0, /* src_mask */
750 0x0000ffff, /* dst_mask */
751 FALSE), /* pcrel_offset */
753 /* GP relative reference. */
754 HOWTO (R_MIPS_GPREL16, /* type */
755 0, /* rightshift */
756 2, /* size (0 = byte, 1 = short, 2 = long) */
757 16, /* bitsize */
758 FALSE, /* pc_relative */
759 0, /* bitpos */
760 complain_overflow_signed, /* complain_on_overflow */
761 mips_elf64_gprel16_reloc, /* special_function */
762 "R_MIPS_GPREL16", /* name */
763 FALSE, /* partial_inplace */
764 0, /* src_mask */
765 0x0000ffff, /* dst_mask */
766 FALSE), /* pcrel_offset */
768 /* Reference to literal section. */
769 HOWTO (R_MIPS_LITERAL, /* type */
770 0, /* rightshift */
771 2, /* size (0 = byte, 1 = short, 2 = long) */
772 16, /* bitsize */
773 FALSE, /* pc_relative */
774 0, /* bitpos */
775 complain_overflow_signed, /* complain_on_overflow */
776 mips_elf64_literal_reloc, /* special_function */
777 "R_MIPS_LITERAL", /* name */
778 FALSE, /* partial_inplace */
779 0, /* src_mask */
780 0x0000ffff, /* dst_mask */
781 FALSE), /* pcrel_offset */
783 /* Reference to global offset table. */
784 HOWTO (R_MIPS_GOT16, /* type */
785 0, /* rightshift */
786 2, /* size (0 = byte, 1 = short, 2 = long) */
787 16, /* bitsize */
788 FALSE, /* pc_relative */
789 0, /* bitpos */
790 complain_overflow_signed, /* complain_on_overflow */
791 mips_elf64_got16_reloc, /* special_function */
792 "R_MIPS_GOT16", /* name */
793 FALSE, /* partial_inplace */
794 0, /* src_mask */
795 0x0000ffff, /* dst_mask */
796 FALSE), /* pcrel_offset */
798 /* 16 bit PC relative reference. */
799 HOWTO (R_MIPS_PC16, /* type */
800 0, /* rightshift */
801 2, /* size (0 = byte, 1 = short, 2 = long) */
802 16, /* bitsize */
803 TRUE, /* pc_relative */
804 0, /* bitpos */
805 complain_overflow_signed, /* complain_on_overflow */
806 bfd_elf_generic_reloc, /* special_function */
807 "R_MIPS_PC16", /* name */
808 FALSE, /* partial_inplace */
809 0, /* src_mask */
810 0x0000ffff, /* dst_mask */
811 TRUE), /* pcrel_offset */
813 /* 16 bit call through global offset table. */
814 HOWTO (R_MIPS_CALL16, /* type */
815 0, /* rightshift */
816 2, /* size (0 = byte, 1 = short, 2 = long) */
817 16, /* bitsize */
818 FALSE, /* pc_relative */
819 0, /* bitpos */
820 complain_overflow_signed, /* complain_on_overflow */
821 bfd_elf_generic_reloc, /* special_function */
822 "R_MIPS_CALL16", /* name */
823 FALSE, /* partial_inplace */
824 0, /* src_mask */
825 0x0000ffff, /* dst_mask */
826 FALSE), /* pcrel_offset */
828 /* 32 bit GP relative reference. */
829 HOWTO (R_MIPS_GPREL32, /* type */
830 0, /* rightshift */
831 2, /* size (0 = byte, 1 = short, 2 = long) */
832 32, /* bitsize */
833 FALSE, /* pc_relative */
834 0, /* bitpos */
835 complain_overflow_dont, /* complain_on_overflow */
836 mips_elf64_gprel32_reloc, /* special_function */
837 "R_MIPS_GPREL32", /* name */
838 FALSE, /* partial_inplace */
839 0, /* src_mask */
840 0xffffffff, /* dst_mask */
841 FALSE), /* pcrel_offset */
843 EMPTY_HOWTO (13),
844 EMPTY_HOWTO (14),
845 EMPTY_HOWTO (15),
847 /* A 5 bit shift field. */
848 HOWTO (R_MIPS_SHIFT5, /* type */
849 0, /* rightshift */
850 2, /* size (0 = byte, 1 = short, 2 = long) */
851 5, /* bitsize */
852 FALSE, /* pc_relative */
853 6, /* bitpos */
854 complain_overflow_bitfield, /* complain_on_overflow */
855 bfd_elf_generic_reloc, /* special_function */
856 "R_MIPS_SHIFT5", /* name */
857 FALSE, /* partial_inplace */
858 0, /* src_mask */
859 0x000007c0, /* dst_mask */
860 FALSE), /* pcrel_offset */
862 /* A 6 bit shift field. */
863 HOWTO (R_MIPS_SHIFT6, /* type */
864 0, /* rightshift */
865 2, /* size (0 = byte, 1 = short, 2 = long) */
866 6, /* bitsize */
867 FALSE, /* pc_relative */
868 6, /* bitpos */
869 complain_overflow_bitfield, /* complain_on_overflow */
870 mips_elf64_shift6_reloc, /* special_function */
871 "R_MIPS_SHIFT6", /* name */
872 FALSE, /* partial_inplace */
873 0, /* src_mask */
874 0x000007c4, /* dst_mask */
875 FALSE), /* pcrel_offset */
877 /* 64 bit relocation. */
878 HOWTO (R_MIPS_64, /* type */
879 0, /* rightshift */
880 4, /* size (0 = byte, 1 = short, 2 = long) */
881 64, /* bitsize */
882 FALSE, /* pc_relative */
883 0, /* bitpos */
884 complain_overflow_dont, /* complain_on_overflow */
885 bfd_elf_generic_reloc, /* special_function */
886 "R_MIPS_64", /* name */
887 FALSE, /* partial_inplace */
888 0, /* src_mask */
889 MINUS_ONE, /* dst_mask */
890 FALSE), /* pcrel_offset */
892 /* Displacement in the global offset table. */
893 HOWTO (R_MIPS_GOT_DISP, /* type */
894 0, /* rightshift */
895 2, /* size (0 = byte, 1 = short, 2 = long) */
896 16, /* bitsize */
897 FALSE, /* pc_relative */
898 0, /* bitpos */
899 complain_overflow_signed, /* complain_on_overflow */
900 bfd_elf_generic_reloc, /* special_function */
901 "R_MIPS_GOT_DISP", /* name */
902 FALSE, /* partial_inplace */
903 0, /* src_mask */
904 0x0000ffff, /* dst_mask */
905 FALSE), /* pcrel_offset */
907 /* Displacement to page pointer in the global offset table. */
908 HOWTO (R_MIPS_GOT_PAGE, /* type */
909 0, /* rightshift */
910 2, /* size (0 = byte, 1 = short, 2 = long) */
911 16, /* bitsize */
912 FALSE, /* pc_relative */
913 0, /* bitpos */
914 complain_overflow_signed, /* complain_on_overflow */
915 bfd_elf_generic_reloc, /* special_function */
916 "R_MIPS_GOT_PAGE", /* name */
917 FALSE, /* partial_inplace */
918 0, /* src_mask */
919 0x0000ffff, /* dst_mask */
920 FALSE), /* pcrel_offset */
922 /* Offset from page pointer in the global offset table. */
923 HOWTO (R_MIPS_GOT_OFST, /* type */
924 0, /* rightshift */
925 2, /* size (0 = byte, 1 = short, 2 = long) */
926 16, /* bitsize */
927 FALSE, /* pc_relative */
928 0, /* bitpos */
929 complain_overflow_signed, /* complain_on_overflow */
930 bfd_elf_generic_reloc, /* special_function */
931 "R_MIPS_GOT_OFST", /* name */
932 FALSE, /* partial_inplace */
933 0, /* src_mask */
934 0x0000ffff, /* dst_mask */
935 FALSE), /* pcrel_offset */
937 /* High 16 bits of displacement in global offset table. */
938 HOWTO (R_MIPS_GOT_HI16, /* type */
939 0, /* rightshift */
940 2, /* size (0 = byte, 1 = short, 2 = long) */
941 16, /* bitsize */
942 FALSE, /* pc_relative */
943 0, /* bitpos */
944 complain_overflow_dont, /* complain_on_overflow */
945 bfd_elf_generic_reloc, /* special_function */
946 "R_MIPS_GOT_HI16", /* name */
947 FALSE, /* partial_inplace */
948 0, /* src_mask */
949 0x0000ffff, /* dst_mask */
950 FALSE), /* pcrel_offset */
952 /* Low 16 bits of displacement in global offset table. */
953 HOWTO (R_MIPS_GOT_LO16, /* type */
954 0, /* rightshift */
955 2, /* size (0 = byte, 1 = short, 2 = long) */
956 16, /* bitsize */
957 FALSE, /* pc_relative */
958 0, /* bitpos */
959 complain_overflow_dont, /* complain_on_overflow */
960 bfd_elf_generic_reloc, /* special_function */
961 "R_MIPS_GOT_LO16", /* name */
962 FALSE, /* partial_inplace */
963 0, /* src_mask */
964 0x0000ffff, /* dst_mask */
965 FALSE), /* pcrel_offset */
967 /* 64 bit substraction. */
968 HOWTO (R_MIPS_SUB, /* type */
969 0, /* rightshift */
970 4, /* size (0 = byte, 1 = short, 2 = long) */
971 64, /* bitsize */
972 FALSE, /* pc_relative */
973 0, /* bitpos */
974 complain_overflow_dont, /* complain_on_overflow */
975 bfd_elf_generic_reloc, /* special_function */
976 "R_MIPS_SUB", /* name */
977 FALSE, /* partial_inplace */
978 0, /* src_mask */
979 MINUS_ONE, /* dst_mask */
980 FALSE), /* pcrel_offset */
982 /* Insert the addend as an instruction. */
983 /* FIXME: Not handled correctly. */
984 HOWTO (R_MIPS_INSERT_A, /* type */
985 0, /* rightshift */
986 2, /* size (0 = byte, 1 = short, 2 = long) */
987 32, /* bitsize */
988 FALSE, /* pc_relative */
989 0, /* bitpos */
990 complain_overflow_dont, /* complain_on_overflow */
991 bfd_elf_generic_reloc, /* special_function */
992 "R_MIPS_INSERT_A", /* name */
993 FALSE, /* partial_inplace */
994 0, /* src_mask */
995 0xffffffff, /* dst_mask */
996 FALSE), /* pcrel_offset */
998 /* Insert the addend as an instruction, and change all relocations
999 to refer to the old instruction at the address. */
1000 /* FIXME: Not handled correctly. */
1001 HOWTO (R_MIPS_INSERT_B, /* type */
1002 0, /* rightshift */
1003 2, /* size (0 = byte, 1 = short, 2 = long) */
1004 32, /* bitsize */
1005 FALSE, /* pc_relative */
1006 0, /* bitpos */
1007 complain_overflow_dont, /* complain_on_overflow */
1008 bfd_elf_generic_reloc, /* special_function */
1009 "R_MIPS_INSERT_B", /* name */
1010 FALSE, /* partial_inplace */
1011 0, /* src_mask */
1012 0xffffffff, /* dst_mask */
1013 FALSE), /* pcrel_offset */
1015 /* Delete a 32 bit instruction. */
1016 /* FIXME: Not handled correctly. */
1017 HOWTO (R_MIPS_DELETE, /* type */
1018 0, /* rightshift */
1019 2, /* size (0 = byte, 1 = short, 2 = long) */
1020 32, /* bitsize */
1021 FALSE, /* pc_relative */
1022 0, /* bitpos */
1023 complain_overflow_dont, /* complain_on_overflow */
1024 bfd_elf_generic_reloc, /* special_function */
1025 "R_MIPS_DELETE", /* name */
1026 FALSE, /* partial_inplace */
1027 0, /* src_mask */
1028 0xffffffff, /* dst_mask */
1029 FALSE), /* pcrel_offset */
1031 /* Get the higher value of a 64 bit addend. */
1032 HOWTO (R_MIPS_HIGHER, /* type */
1033 0, /* rightshift */
1034 2, /* size (0 = byte, 1 = short, 2 = long) */
1035 16, /* bitsize */
1036 FALSE, /* pc_relative */
1037 0, /* bitpos */
1038 complain_overflow_dont, /* complain_on_overflow */
1039 bfd_elf_generic_reloc, /* special_function */
1040 "R_MIPS_HIGHER", /* name */
1041 FALSE, /* partial_inplace */
1042 0, /* src_mask */
1043 0x0000ffff, /* dst_mask */
1044 FALSE), /* pcrel_offset */
1046 /* Get the highest value of a 64 bit addend. */
1047 HOWTO (R_MIPS_HIGHEST, /* type */
1048 0, /* rightshift */
1049 2, /* size (0 = byte, 1 = short, 2 = long) */
1050 16, /* bitsize */
1051 FALSE, /* pc_relative */
1052 0, /* bitpos */
1053 complain_overflow_dont, /* complain_on_overflow */
1054 bfd_elf_generic_reloc, /* special_function */
1055 "R_MIPS_HIGHEST", /* name */
1056 FALSE, /* partial_inplace */
1057 0, /* src_mask */
1058 0x0000ffff, /* dst_mask */
1059 FALSE), /* pcrel_offset */
1061 /* High 16 bits of displacement in global offset table. */
1062 HOWTO (R_MIPS_CALL_HI16, /* type */
1063 0, /* rightshift */
1064 2, /* size (0 = byte, 1 = short, 2 = long) */
1065 16, /* bitsize */
1066 FALSE, /* pc_relative */
1067 0, /* bitpos */
1068 complain_overflow_dont, /* complain_on_overflow */
1069 bfd_elf_generic_reloc, /* special_function */
1070 "R_MIPS_CALL_HI16", /* name */
1071 FALSE, /* partial_inplace */
1072 0, /* src_mask */
1073 0x0000ffff, /* dst_mask */
1074 FALSE), /* pcrel_offset */
1076 /* Low 16 bits of displacement in global offset table. */
1077 HOWTO (R_MIPS_CALL_LO16, /* type */
1078 0, /* rightshift */
1079 2, /* size (0 = byte, 1 = short, 2 = long) */
1080 16, /* bitsize */
1081 FALSE, /* pc_relative */
1082 0, /* bitpos */
1083 complain_overflow_dont, /* complain_on_overflow */
1084 bfd_elf_generic_reloc, /* special_function */
1085 "R_MIPS_CALL_LO16", /* name */
1086 FALSE, /* partial_inplace */
1087 0, /* src_mask */
1088 0x0000ffff, /* dst_mask */
1089 FALSE), /* pcrel_offset */
1091 /* Section displacement, used by an associated event location section. */
1092 HOWTO (R_MIPS_SCN_DISP, /* type */
1093 0, /* rightshift */
1094 2, /* size (0 = byte, 1 = short, 2 = long) */
1095 32, /* bitsize */
1096 FALSE, /* pc_relative */
1097 0, /* bitpos */
1098 complain_overflow_dont, /* complain_on_overflow */
1099 bfd_elf_generic_reloc, /* special_function */
1100 "R_MIPS_SCN_DISP", /* name */
1101 FALSE, /* partial_inplace */
1102 0, /* src_mask */
1103 0xffffffff, /* dst_mask */
1104 FALSE), /* pcrel_offset */
1106 HOWTO (R_MIPS_REL16, /* type */
1107 0, /* rightshift */
1108 1, /* size (0 = byte, 1 = short, 2 = long) */
1109 16, /* bitsize */
1110 FALSE, /* pc_relative */
1111 0, /* bitpos */
1112 complain_overflow_signed, /* complain_on_overflow */
1113 bfd_elf_generic_reloc, /* special_function */
1114 "R_MIPS_REL16", /* name */
1115 FALSE, /* partial_inplace */
1116 0, /* src_mask */
1117 0xffff, /* dst_mask */
1118 FALSE), /* pcrel_offset */
1120 /* These two are obsolete. */
1121 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1122 EMPTY_HOWTO (R_MIPS_PJUMP),
1124 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1125 It must be used for multigot GOT's (and only there). */
1126 HOWTO (R_MIPS_RELGOT, /* type */
1127 0, /* rightshift */
1128 2, /* size (0 = byte, 1 = short, 2 = long) */
1129 32, /* bitsize */
1130 FALSE, /* pc_relative */
1131 0, /* bitpos */
1132 complain_overflow_dont, /* complain_on_overflow */
1133 bfd_elf_generic_reloc, /* special_function */
1134 "R_MIPS_RELGOT", /* name */
1135 FALSE, /* partial_inplace */
1136 0, /* src_mask */
1137 0xffffffff, /* dst_mask */
1138 FALSE), /* pcrel_offset */
1140 /* Protected jump conversion. This is an optimization hint. No
1141 relocation is required for correctness. */
1142 HOWTO (R_MIPS_JALR, /* type */
1143 0, /* rightshift */
1144 2, /* size (0 = byte, 1 = short, 2 = long) */
1145 32, /* bitsize */
1146 FALSE, /* pc_relative */
1147 0, /* bitpos */
1148 complain_overflow_dont, /* complain_on_overflow */
1149 bfd_elf_generic_reloc, /* special_function */
1150 "R_MIPS_JALR", /* name */
1151 FALSE, /* partial_inplace */
1152 0, /* src_mask */
1153 0x00000000, /* dst_mask */
1154 FALSE), /* pcrel_offset */
1157 /* The reloc used for the mips16 jump instruction. */
1158 static reloc_howto_type elf_mips16_jump_howto =
1159 HOWTO (R_MIPS16_26, /* type */
1160 2, /* rightshift */
1161 2, /* size (0 = byte, 1 = short, 2 = long) */
1162 26, /* bitsize */
1163 FALSE, /* pc_relative */
1164 0, /* bitpos */
1165 complain_overflow_dont, /* complain_on_overflow */
1166 /* This needs complex overflow
1167 detection, because the upper four
1168 bits must match the PC. */
1169 mips16_jump_reloc, /* special_function */
1170 "R_MIPS16_26", /* name */
1171 TRUE, /* partial_inplace */
1172 0x3ffffff, /* src_mask */
1173 0x3ffffff, /* dst_mask */
1174 FALSE); /* pcrel_offset */
1176 /* The reloc used for the mips16 gprel instruction. */
1177 static reloc_howto_type elf_mips16_gprel_howto =
1178 HOWTO (R_MIPS16_GPREL, /* type */
1179 0, /* rightshift */
1180 2, /* size (0 = byte, 1 = short, 2 = long) */
1181 16, /* bitsize */
1182 FALSE, /* pc_relative */
1183 0, /* bitpos */
1184 complain_overflow_signed, /* complain_on_overflow */
1185 mips16_gprel_reloc, /* special_function */
1186 "R_MIPS16_GPREL", /* name */
1187 TRUE, /* partial_inplace */
1188 0x07ff001f, /* src_mask */
1189 0x07ff001f, /* dst_mask */
1190 FALSE); /* pcrel_offset */
1192 /* GNU extension to record C++ vtable hierarchy */
1193 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1194 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1195 0, /* rightshift */
1196 2, /* size (0 = byte, 1 = short, 2 = long) */
1197 0, /* bitsize */
1198 FALSE, /* pc_relative */
1199 0, /* bitpos */
1200 complain_overflow_dont, /* complain_on_overflow */
1201 NULL, /* special_function */
1202 "R_MIPS_GNU_VTINHERIT", /* name */
1203 FALSE, /* partial_inplace */
1204 0, /* src_mask */
1205 0, /* dst_mask */
1206 FALSE); /* pcrel_offset */
1208 /* GNU extension to record C++ vtable member usage */
1209 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1210 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1211 0, /* rightshift */
1212 2, /* size (0 = byte, 1 = short, 2 = long) */
1213 0, /* bitsize */
1214 FALSE, /* pc_relative */
1215 0, /* bitpos */
1216 complain_overflow_dont, /* complain_on_overflow */
1217 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1218 "R_MIPS_GNU_VTENTRY", /* name */
1219 FALSE, /* partial_inplace */
1220 0, /* src_mask */
1221 0, /* dst_mask */
1222 FALSE); /* pcrel_offset */
1224 /* Swap in a MIPS 64-bit Rel reloc. */
1226 static void
1227 mips_elf64_swap_reloc_in (abfd, src, dst)
1228 bfd *abfd;
1229 const Elf64_Mips_External_Rel *src;
1230 Elf64_Mips_Internal_Rela *dst;
1232 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1233 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1234 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1235 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1236 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1237 dst->r_type = H_GET_8 (abfd, src->r_type);
1238 dst->r_addend = 0;
1241 /* Swap in a MIPS 64-bit Rela reloc. */
1243 static void
1244 mips_elf64_swap_reloca_in (abfd, src, dst)
1245 bfd *abfd;
1246 const Elf64_Mips_External_Rela *src;
1247 Elf64_Mips_Internal_Rela *dst;
1249 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1250 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1251 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1252 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1253 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1254 dst->r_type = H_GET_8 (abfd, src->r_type);
1255 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1258 /* Swap out a MIPS 64-bit Rel reloc. */
1260 static void
1261 mips_elf64_swap_reloc_out (abfd, src, dst)
1262 bfd *abfd;
1263 const Elf64_Mips_Internal_Rela *src;
1264 Elf64_Mips_External_Rel *dst;
1266 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1267 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1268 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1269 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1270 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1271 H_PUT_8 (abfd, src->r_type, dst->r_type);
1274 /* Swap out a MIPS 64-bit Rela reloc. */
1276 static void
1277 mips_elf64_swap_reloca_out (abfd, src, dst)
1278 bfd *abfd;
1279 const Elf64_Mips_Internal_Rela *src;
1280 Elf64_Mips_External_Rela *dst;
1282 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1283 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1284 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1285 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1286 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1287 H_PUT_8 (abfd, src->r_type, dst->r_type);
1288 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1291 /* Swap in a MIPS 64-bit Rel reloc. */
1293 static void
1294 mips_elf64_be_swap_reloc_in (abfd, src, dst)
1295 bfd *abfd;
1296 const bfd_byte *src;
1297 Elf_Internal_Rela *dst;
1299 Elf64_Mips_Internal_Rela mirel;
1301 mips_elf64_swap_reloc_in (abfd,
1302 (const Elf64_Mips_External_Rel *) src,
1303 &mirel);
1305 dst[0].r_offset = mirel.r_offset;
1306 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1307 dst[0].r_addend = 0;
1308 dst[1].r_offset = mirel.r_offset;
1309 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1310 dst[1].r_addend = 0;
1311 dst[2].r_offset = mirel.r_offset;
1312 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1313 dst[2].r_addend = 0;
1316 /* Swap in a MIPS 64-bit Rela reloc. */
1318 static void
1319 mips_elf64_be_swap_reloca_in (abfd, src, dst)
1320 bfd *abfd;
1321 const bfd_byte *src;
1322 Elf_Internal_Rela *dst;
1324 Elf64_Mips_Internal_Rela mirela;
1326 mips_elf64_swap_reloca_in (abfd,
1327 (const Elf64_Mips_External_Rela *) src,
1328 &mirela);
1330 dst[0].r_offset = mirela.r_offset;
1331 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1332 dst[0].r_addend = mirela.r_addend;
1333 dst[1].r_offset = mirela.r_offset;
1334 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1335 dst[1].r_addend = 0;
1336 dst[2].r_offset = mirela.r_offset;
1337 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1338 dst[2].r_addend = 0;
1341 /* Swap out a MIPS 64-bit Rel reloc. */
1343 static void
1344 mips_elf64_be_swap_reloc_out (abfd, src, dst)
1345 bfd *abfd;
1346 const Elf_Internal_Rela *src;
1347 bfd_byte *dst;
1349 Elf64_Mips_Internal_Rela mirel;
1351 mirel.r_offset = src[0].r_offset;
1352 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1353 #if 0
1354 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1355 #endif
1357 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1358 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1359 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1360 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1361 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1363 mips_elf64_swap_reloc_out (abfd, &mirel,
1364 (Elf64_Mips_External_Rel *) dst);
1367 /* Swap out a MIPS 64-bit Rela reloc. */
1369 static void
1370 mips_elf64_be_swap_reloca_out (abfd, src, dst)
1371 bfd *abfd;
1372 const Elf_Internal_Rela *src;
1373 bfd_byte *dst;
1375 Elf64_Mips_Internal_Rela mirela;
1377 mirela.r_offset = src[0].r_offset;
1378 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1379 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1381 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1382 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1383 mirela.r_addend = src[0].r_addend;
1384 BFD_ASSERT(src[1].r_addend == 0);
1385 BFD_ASSERT(src[2].r_addend == 0);
1387 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1388 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1389 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1391 mips_elf64_swap_reloca_out (abfd, &mirela,
1392 (Elf64_Mips_External_Rela *) dst);
1395 /* Do a R_MIPS_HI16 relocation. */
1397 static bfd_reloc_status_type
1398 mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data, input_section,
1399 output_bfd, error_message)
1400 bfd *abfd ATTRIBUTE_UNUSED;
1401 arelent *reloc_entry;
1402 asymbol *symbol;
1403 PTR data ATTRIBUTE_UNUSED;
1404 asection *input_section;
1405 bfd *output_bfd;
1406 char **error_message ATTRIBUTE_UNUSED;
1408 /* If we're relocating, and this is an external symbol, we don't
1409 want to change anything. */
1410 if (output_bfd != (bfd *) NULL
1411 && (symbol->flags & BSF_SECTION_SYM) == 0
1412 && (! reloc_entry->howto->partial_inplace
1413 || reloc_entry->addend == 0))
1415 reloc_entry->address += input_section->output_offset;
1416 return bfd_reloc_ok;
1419 if (((reloc_entry->addend & 0xffff) + 0x8000) & ~0xffff)
1420 reloc_entry->addend += 0x8000;
1422 return bfd_reloc_continue;
1425 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1426 table used for PIC code. If the symbol is an external symbol, the
1427 instruction is modified to contain the offset of the appropriate
1428 entry in the global offset table. If the symbol is a section
1429 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1430 addends are combined to form the real addend against the section
1431 symbol; the GOT16 is modified to contain the offset of an entry in
1432 the global offset table, and the LO16 is modified to offset it
1433 appropriately. Thus an offset larger than 16 bits requires a
1434 modified value in the global offset table.
1436 This implementation suffices for the assembler, but the linker does
1437 not yet know how to create global offset tables. */
1439 static bfd_reloc_status_type
1440 mips_elf64_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1441 output_bfd, error_message)
1442 bfd *abfd;
1443 arelent *reloc_entry;
1444 asymbol *symbol;
1445 PTR data;
1446 asection *input_section;
1447 bfd *output_bfd;
1448 char **error_message;
1450 /* If we're relocating, and this is a local symbol, we can handle it
1451 just like an R_MIPS_HI16. */
1452 if (output_bfd != (bfd *) NULL
1453 && (symbol->flags & BSF_SECTION_SYM) != 0)
1454 return mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data,
1455 input_section, output_bfd, error_message);
1458 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1459 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1460 input_section, output_bfd, error_message);
1463 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1464 dangerous relocation. */
1466 static bfd_boolean
1467 mips_elf64_assign_gp (output_bfd, pgp)
1468 bfd *output_bfd;
1469 bfd_vma *pgp;
1471 unsigned int count;
1472 asymbol **sym;
1473 unsigned int i;
1475 /* If we've already figured out what GP will be, just return it. */
1476 *pgp = _bfd_get_gp_value (output_bfd);
1477 if (*pgp)
1478 return TRUE;
1480 count = bfd_get_symcount (output_bfd);
1481 sym = bfd_get_outsymbols (output_bfd);
1483 /* The linker script will have created a symbol named `_gp' with the
1484 appropriate value. */
1485 if (sym == (asymbol **) NULL)
1486 i = count;
1487 else
1489 for (i = 0; i < count; i++, sym++)
1491 register const char *name;
1493 name = bfd_asymbol_name (*sym);
1494 if (*name == '_' && strcmp (name, "_gp") == 0)
1496 *pgp = bfd_asymbol_value (*sym);
1497 _bfd_set_gp_value (output_bfd, *pgp);
1498 break;
1503 if (i >= count)
1505 /* Only get the error once. */
1506 *pgp = 4;
1507 _bfd_set_gp_value (output_bfd, *pgp);
1508 return FALSE;
1511 return TRUE;
1514 /* We have to figure out the gp value, so that we can adjust the
1515 symbol value correctly. We look up the symbol _gp in the output
1516 BFD. If we can't find it, we're stuck. We cache it in the ELF
1517 target data. We don't need to adjust the symbol value for an
1518 external symbol if we are producing relocateable output. */
1520 static bfd_reloc_status_type
1521 mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, pgp)
1522 bfd *output_bfd;
1523 asymbol *symbol;
1524 bfd_boolean relocateable;
1525 char **error_message;
1526 bfd_vma *pgp;
1528 if (bfd_is_und_section (symbol->section)
1529 && ! relocateable)
1531 *pgp = 0;
1532 return bfd_reloc_undefined;
1535 *pgp = _bfd_get_gp_value (output_bfd);
1536 if (*pgp == 0
1537 && (! relocateable
1538 || (symbol->flags & BSF_SECTION_SYM) != 0))
1540 if (relocateable)
1542 /* Make up a value. */
1543 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1544 _bfd_set_gp_value (output_bfd, *pgp);
1546 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1548 *error_message =
1549 (char *) _("GP relative relocation when _gp not defined");
1550 return bfd_reloc_dangerous;
1554 return bfd_reloc_ok;
1557 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1558 become the offset from the gp register. */
1560 static bfd_reloc_status_type
1561 mips_elf64_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
1562 output_bfd, error_message)
1563 bfd *abfd;
1564 arelent *reloc_entry;
1565 asymbol *symbol;
1566 PTR data;
1567 asection *input_section;
1568 bfd *output_bfd;
1569 char **error_message;
1571 bfd_boolean relocateable;
1572 bfd_reloc_status_type ret;
1573 bfd_vma gp;
1575 /* If we're relocating, and this is an external symbol with no
1576 addend, we don't want to change anything. We will only have an
1577 addend if this is a newly created reloc, not read from an ELF
1578 file. */
1579 if (output_bfd != (bfd *) NULL
1580 && (symbol->flags & BSF_SECTION_SYM) == 0
1581 && (! reloc_entry->howto->partial_inplace
1582 || reloc_entry->addend == 0))
1584 reloc_entry->address += input_section->output_offset;
1585 return bfd_reloc_ok;
1588 if (output_bfd != (bfd *) NULL)
1589 relocateable = TRUE;
1590 else
1592 relocateable = FALSE;
1593 output_bfd = symbol->section->output_section->owner;
1596 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1597 &gp);
1598 if (ret != bfd_reloc_ok)
1599 return ret;
1601 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1602 input_section, relocateable,
1603 data, gp);
1606 /* Do a R_MIPS_LITERAL relocation. */
1608 static bfd_reloc_status_type
1609 mips_elf64_literal_reloc (abfd, reloc_entry, symbol, data, input_section,
1610 output_bfd, error_message)
1611 bfd *abfd;
1612 arelent *reloc_entry;
1613 asymbol *symbol;
1614 PTR data;
1615 asection *input_section;
1616 bfd *output_bfd;
1617 char **error_message;
1619 bfd_boolean relocateable;
1620 bfd_reloc_status_type ret;
1621 bfd_vma gp;
1623 /* If we're relocating, and this is an external symbol, we don't
1624 want to change anything. */
1625 if (output_bfd != (bfd *) NULL
1626 && (symbol->flags & BSF_SECTION_SYM) == 0
1627 && (! reloc_entry->howto->partial_inplace
1628 || reloc_entry->addend == 0))
1630 reloc_entry->address += input_section->output_offset;
1631 return bfd_reloc_ok;
1634 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1635 if (output_bfd != (bfd *) NULL)
1636 relocateable = TRUE;
1637 else
1639 relocateable = FALSE;
1640 output_bfd = symbol->section->output_section->owner;
1643 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1644 &gp);
1645 if (ret != bfd_reloc_ok)
1646 return ret;
1648 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1649 input_section, relocateable,
1650 data, gp);
1653 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1654 become the offset from the gp register. */
1656 static bfd_reloc_status_type
1657 mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section,
1658 output_bfd, error_message)
1659 bfd *abfd;
1660 arelent *reloc_entry;
1661 asymbol *symbol;
1662 PTR data;
1663 asection *input_section;
1664 bfd *output_bfd;
1665 char **error_message;
1667 bfd_boolean relocateable;
1668 bfd_reloc_status_type ret;
1669 bfd_vma gp;
1670 bfd_vma relocation;
1671 unsigned long val;
1673 /* If we're relocating, and this is an external symbol with no
1674 addend, we don't want to change anything. We will only have an
1675 addend if this is a newly created reloc, not read from an ELF
1676 file. */
1677 if (output_bfd != (bfd *) NULL
1678 && (symbol->flags & BSF_SECTION_SYM) == 0
1679 && reloc_entry->addend == 0)
1681 *error_message = (char *)
1682 _("32bits gp relative relocation occurs for an external symbol");
1683 return bfd_reloc_outofrange;
1686 if (output_bfd != (bfd *) NULL)
1688 relocateable = TRUE;
1689 gp = _bfd_get_gp_value (output_bfd);
1691 else
1693 relocateable = FALSE;
1694 output_bfd = symbol->section->output_section->owner;
1696 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable,
1697 error_message, &gp);
1698 if (ret != bfd_reloc_ok)
1699 return ret;
1702 if (bfd_is_com_section (symbol->section))
1703 relocation = 0;
1704 else
1705 relocation = symbol->value;
1707 relocation += symbol->section->output_section->vma;
1708 relocation += symbol->section->output_offset;
1710 if (reloc_entry->address > input_section->_cooked_size)
1711 return bfd_reloc_outofrange;
1713 if (reloc_entry->howto->src_mask == 0)
1715 /* This case arises with the 64-bit MIPS ELF ABI. */
1716 val = 0;
1718 else
1719 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1721 /* Set val to the offset into the section or symbol. */
1722 val += reloc_entry->addend;
1724 /* Adjust val for the final section location and GP value. If we
1725 are producing relocateable output, we don't want to do this for
1726 an external symbol. */
1727 if (! relocateable
1728 || (symbol->flags & BSF_SECTION_SYM) != 0)
1729 val += relocation - gp;
1731 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1733 if (relocateable)
1734 reloc_entry->address += input_section->output_offset;
1736 return bfd_reloc_ok;
1739 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1740 the rest is at bits 6-10. The bitpos already got right by the howto. */
1742 static bfd_reloc_status_type
1743 mips_elf64_shift6_reloc (abfd, reloc_entry, symbol, data, input_section,
1744 output_bfd, error_message)
1745 bfd *abfd ATTRIBUTE_UNUSED;
1746 arelent *reloc_entry;
1747 asymbol *symbol;
1748 PTR data ATTRIBUTE_UNUSED;
1749 asection *input_section;
1750 bfd *output_bfd;
1751 char **error_message ATTRIBUTE_UNUSED;
1753 /* If we're relocating, and this is an external symbol, we don't
1754 want to change anything. */
1755 if (output_bfd != (bfd *) NULL
1756 && (symbol->flags & BSF_SECTION_SYM) == 0
1757 && (! reloc_entry->howto->partial_inplace
1758 || reloc_entry->addend == 0))
1760 reloc_entry->address += input_section->output_offset;
1761 return bfd_reloc_ok;
1764 reloc_entry->addend = (reloc_entry->addend & 0x00007c0)
1765 | (reloc_entry->addend & 0x00000800) >> 9;
1767 return bfd_reloc_continue;
1770 /* Handle a mips16 jump. */
1772 static bfd_reloc_status_type
1773 mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
1774 output_bfd, error_message)
1775 bfd *abfd ATTRIBUTE_UNUSED;
1776 arelent *reloc_entry;
1777 asymbol *symbol;
1778 PTR data ATTRIBUTE_UNUSED;
1779 asection *input_section;
1780 bfd *output_bfd;
1781 char **error_message ATTRIBUTE_UNUSED;
1783 if (output_bfd != (bfd *) NULL
1784 && (symbol->flags & BSF_SECTION_SYM) == 0
1785 && (! reloc_entry->howto->partial_inplace
1786 || reloc_entry->addend == 0))
1788 reloc_entry->address += input_section->output_offset;
1789 return bfd_reloc_ok;
1792 /* FIXME. */
1794 static bfd_boolean warned;
1796 if (! warned)
1797 (*_bfd_error_handler)
1798 (_("Linking mips16 objects into %s format is not supported"),
1799 bfd_get_target (input_section->output_section->owner));
1800 warned = TRUE;
1803 return bfd_reloc_undefined;
1806 /* Handle a mips16 GP relative reloc. */
1808 static bfd_reloc_status_type
1809 mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
1810 output_bfd, error_message)
1811 bfd *abfd;
1812 arelent *reloc_entry;
1813 asymbol *symbol;
1814 PTR data;
1815 asection *input_section;
1816 bfd *output_bfd;
1817 char **error_message;
1819 bfd_boolean relocateable;
1820 bfd_reloc_status_type ret;
1821 bfd_vma gp;
1822 unsigned short extend, insn;
1823 unsigned long final;
1825 /* If we're relocating, and this is an external symbol with no
1826 addend, we don't want to change anything. We will only have an
1827 addend if this is a newly created reloc, not read from an ELF
1828 file. */
1829 if (output_bfd != NULL
1830 && (symbol->flags & BSF_SECTION_SYM) == 0
1831 && reloc_entry->addend == 0)
1833 reloc_entry->address += input_section->output_offset;
1834 return bfd_reloc_ok;
1837 if (output_bfd != NULL)
1838 relocateable = TRUE;
1839 else
1841 relocateable = FALSE;
1842 output_bfd = symbol->section->output_section->owner;
1845 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1846 &gp);
1847 if (ret != bfd_reloc_ok)
1848 return ret;
1850 if (reloc_entry->address > input_section->_cooked_size)
1851 return bfd_reloc_outofrange;
1853 /* Pick up the mips16 extend instruction and the real instruction. */
1854 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1855 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1857 /* Stuff the current addend back as a 32 bit value, do the usual
1858 relocation, and then clean up. */
1859 bfd_put_32 (abfd,
1860 (bfd_vma) (((extend & 0x1f) << 11)
1861 | (extend & 0x7e0)
1862 | (insn & 0x1f)),
1863 (bfd_byte *) data + reloc_entry->address);
1865 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1866 input_section, relocateable, data, gp);
1868 final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1869 bfd_put_16 (abfd,
1870 (bfd_vma) ((extend & 0xf800)
1871 | ((final >> 11) & 0x1f)
1872 | (final & 0x7e0)),
1873 (bfd_byte *) data + reloc_entry->address);
1874 bfd_put_16 (abfd,
1875 (bfd_vma) ((insn & 0xffe0)
1876 | (final & 0x1f)),
1877 (bfd_byte *) data + reloc_entry->address + 2);
1879 return ret;
1882 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1884 struct elf_reloc_map {
1885 bfd_reloc_code_real_type bfd_val;
1886 enum elf_mips_reloc_type elf_val;
1889 static const struct elf_reloc_map mips_reloc_map[] =
1891 { BFD_RELOC_NONE, R_MIPS_NONE },
1892 { BFD_RELOC_16, R_MIPS_16 },
1893 { BFD_RELOC_32, R_MIPS_32 },
1894 /* There is no BFD reloc for R_MIPS_REL32. */
1895 { BFD_RELOC_64, R_MIPS_64 },
1896 { BFD_RELOC_CTOR, R_MIPS_64 },
1897 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1898 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1899 { BFD_RELOC_LO16, R_MIPS_LO16 },
1900 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1901 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1902 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1903 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1904 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1905 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1906 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1907 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1908 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1909 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1910 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1911 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1912 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1913 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1914 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1915 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1916 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1917 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1918 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1919 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1920 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1921 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1922 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1923 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1924 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1925 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1928 /* Given a BFD reloc type, return a howto structure. */
1930 static reloc_howto_type *
1931 bfd_elf64_bfd_reloc_type_lookup (abfd, code)
1932 bfd *abfd ATTRIBUTE_UNUSED;
1933 bfd_reloc_code_real_type code;
1935 unsigned int i;
1936 /* FIXME: We default to RELA here instead of choosing the right
1937 relocation variant. */
1938 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
1940 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1941 i++)
1943 if (mips_reloc_map[i].bfd_val == code)
1944 return &howto_table[(int) mips_reloc_map[i].elf_val];
1947 switch (code)
1949 case BFD_RELOC_MIPS16_JMP:
1950 return &elf_mips16_jump_howto;
1951 case BFD_RELOC_MIPS16_GPREL:
1952 return &elf_mips16_gprel_howto;
1953 case BFD_RELOC_VTABLE_INHERIT:
1954 return &elf_mips_gnu_vtinherit_howto;
1955 case BFD_RELOC_VTABLE_ENTRY:
1956 return &elf_mips_gnu_vtentry_howto;
1957 default:
1958 bfd_set_error (bfd_error_bad_value);
1959 return NULL;
1963 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1965 static reloc_howto_type *
1966 mips_elf64_rtype_to_howto (r_type, rela_p)
1967 unsigned int r_type;
1968 bfd_boolean rela_p;
1970 switch (r_type)
1972 case R_MIPS16_26:
1973 return &elf_mips16_jump_howto;
1974 case R_MIPS16_GPREL:
1975 return &elf_mips16_gprel_howto;
1976 case R_MIPS_GNU_VTINHERIT:
1977 return &elf_mips_gnu_vtinherit_howto;
1978 case R_MIPS_GNU_VTENTRY:
1979 return &elf_mips_gnu_vtentry_howto;
1980 default:
1981 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1982 if (rela_p)
1983 return &mips_elf64_howto_table_rela[r_type];
1984 else
1985 return &mips_elf64_howto_table_rel[r_type];
1986 break;
1990 /* Prevent relocation handling by bfd for MIPS ELF64. */
1992 static void
1993 mips_elf64_info_to_howto_rel (abfd, cache_ptr, dst)
1994 bfd *abfd ATTRIBUTE_UNUSED;
1995 arelent *cache_ptr ATTRIBUTE_UNUSED;
1996 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
1998 BFD_ASSERT (0);
2001 static void
2002 mips_elf64_info_to_howto_rela (abfd, cache_ptr, dst)
2003 bfd *abfd ATTRIBUTE_UNUSED;
2004 arelent *cache_ptr ATTRIBUTE_UNUSED;
2005 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
2007 BFD_ASSERT (0);
2010 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2011 to three relocs, we must tell the user to allocate more space. */
2013 static long
2014 mips_elf64_get_reloc_upper_bound (abfd, sec)
2015 bfd *abfd ATTRIBUTE_UNUSED;
2016 asection *sec;
2018 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2021 /* Read the relocations from one reloc section. */
2023 static bfd_boolean
2024 mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
2025 bfd *abfd;
2026 asection *asect;
2027 asymbol **symbols;
2028 const Elf_Internal_Shdr *rel_hdr;
2030 PTR allocated = NULL;
2031 bfd_byte *native_relocs;
2032 arelent *relents;
2033 arelent *relent;
2034 bfd_vma count;
2035 bfd_vma i;
2036 int entsize;
2037 reloc_howto_type *howto_table;
2039 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
2040 if (allocated == NULL)
2041 return FALSE;
2043 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2044 || (bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
2045 goto error_return;
2047 native_relocs = (bfd_byte *) allocated;
2049 relents = asect->relocation + asect->reloc_count;
2051 entsize = rel_hdr->sh_entsize;
2052 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2053 || entsize == sizeof (Elf64_Mips_External_Rela));
2055 count = rel_hdr->sh_size / entsize;
2057 if (entsize == sizeof (Elf64_Mips_External_Rel))
2058 howto_table = mips_elf64_howto_table_rel;
2059 else
2060 howto_table = mips_elf64_howto_table_rela;
2062 relent = relents;
2063 for (i = 0; i < count; i++, native_relocs += entsize)
2065 Elf64_Mips_Internal_Rela rela;
2066 bfd_boolean used_sym, used_ssym;
2067 int ir;
2069 if (entsize == sizeof (Elf64_Mips_External_Rela))
2070 mips_elf64_swap_reloca_in (abfd,
2071 (Elf64_Mips_External_Rela *) native_relocs,
2072 &rela);
2073 else
2074 mips_elf64_swap_reloc_in (abfd,
2075 (Elf64_Mips_External_Rel *) native_relocs,
2076 &rela);
2078 /* Each entry represents exactly three actual relocations. */
2080 used_sym = FALSE;
2081 used_ssym = FALSE;
2082 for (ir = 0; ir < 3; ir++)
2084 enum elf_mips_reloc_type type;
2086 switch (ir)
2088 default:
2089 abort ();
2090 case 0:
2091 type = (enum elf_mips_reloc_type) rela.r_type;
2092 break;
2093 case 1:
2094 type = (enum elf_mips_reloc_type) rela.r_type2;
2095 break;
2096 case 2:
2097 type = (enum elf_mips_reloc_type) rela.r_type3;
2098 break;
2101 /* Some types require symbols, whereas some do not. */
2102 switch (type)
2104 case R_MIPS_NONE:
2105 case R_MIPS_LITERAL:
2106 case R_MIPS_INSERT_A:
2107 case R_MIPS_INSERT_B:
2108 case R_MIPS_DELETE:
2109 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2110 break;
2112 default:
2113 if (! used_sym)
2115 if (rela.r_sym == 0)
2116 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2117 else
2119 asymbol **ps, *s;
2121 ps = symbols + rela.r_sym - 1;
2122 s = *ps;
2123 if ((s->flags & BSF_SECTION_SYM) == 0)
2124 relent->sym_ptr_ptr = ps;
2125 else
2126 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2129 used_sym = TRUE;
2131 else if (! used_ssym)
2133 switch (rela.r_ssym)
2135 case RSS_UNDEF:
2136 relent->sym_ptr_ptr =
2137 bfd_abs_section_ptr->symbol_ptr_ptr;
2138 break;
2140 case RSS_GP:
2141 case RSS_GP0:
2142 case RSS_LOC:
2143 /* FIXME: I think these need to be handled using
2144 special howto structures. */
2145 BFD_ASSERT (0);
2146 break;
2148 default:
2149 BFD_ASSERT (0);
2150 break;
2153 used_ssym = TRUE;
2155 else
2156 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2158 break;
2161 /* The address of an ELF reloc is section relative for an
2162 object file, and absolute for an executable file or
2163 shared library. The address of a BFD reloc is always
2164 section relative. */
2165 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2166 relent->address = rela.r_offset;
2167 else
2168 relent->address = rela.r_offset - asect->vma;
2170 relent->addend = rela.r_addend;
2172 relent->howto = &howto_table[(int) type];
2174 ++relent;
2178 asect->reloc_count += (relent - relents) / 3;
2180 if (allocated != NULL)
2181 free (allocated);
2183 return TRUE;
2185 error_return:
2186 if (allocated != NULL)
2187 free (allocated);
2188 return FALSE;
2191 /* Read the relocations. On Irix 6, there can be two reloc sections
2192 associated with a single data section. */
2194 static bfd_boolean
2195 mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
2196 bfd *abfd;
2197 asection *asect;
2198 asymbol **symbols;
2199 bfd_boolean dynamic;
2201 bfd_size_type amt;
2202 struct bfd_elf_section_data * const d = elf_section_data (asect);
2204 if (dynamic)
2206 bfd_set_error (bfd_error_invalid_operation);
2207 return FALSE;
2210 if (asect->relocation != NULL
2211 || (asect->flags & SEC_RELOC) == 0
2212 || asect->reloc_count == 0)
2213 return TRUE;
2215 /* Allocate space for 3 arelent structures for each Rel structure. */
2216 amt = asect->reloc_count;
2217 amt *= 3 * sizeof (arelent);
2218 asect->relocation = (arelent *) bfd_alloc (abfd, amt);
2219 if (asect->relocation == NULL)
2220 return FALSE;
2222 /* The slurp_one_reloc_table routine increments reloc_count. */
2223 asect->reloc_count = 0;
2225 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
2226 return FALSE;
2227 if (d->rel_hdr2 != NULL)
2229 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
2230 d->rel_hdr2))
2231 return FALSE;
2234 return TRUE;
2237 /* Write out the relocations. */
2239 static void
2240 mips_elf64_write_relocs (abfd, sec, data)
2241 bfd *abfd;
2242 asection *sec;
2243 PTR data;
2245 bfd_boolean *failedp = (bfd_boolean *) data;
2246 int count;
2247 Elf_Internal_Shdr *rel_hdr;
2248 unsigned int idx;
2250 /* If we have already failed, don't do anything. */
2251 if (*failedp)
2252 return;
2254 if ((sec->flags & SEC_RELOC) == 0)
2255 return;
2257 /* The linker backend writes the relocs out itself, and sets the
2258 reloc_count field to zero to inhibit writing them here. Also,
2259 sometimes the SEC_RELOC flag gets set even when there aren't any
2260 relocs. */
2261 if (sec->reloc_count == 0)
2262 return;
2264 /* We can combine up to three relocs that refer to the same address
2265 if the latter relocs have no associated symbol. */
2266 count = 0;
2267 for (idx = 0; idx < sec->reloc_count; idx++)
2269 bfd_vma addr;
2270 unsigned int i;
2272 ++count;
2274 addr = sec->orelocation[idx]->address;
2275 for (i = 0; i < 2; i++)
2277 arelent *r;
2279 if (idx + 1 >= sec->reloc_count)
2280 break;
2281 r = sec->orelocation[idx + 1];
2282 if (r->address != addr
2283 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2284 || (*r->sym_ptr_ptr)->value != 0)
2285 break;
2287 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2289 ++idx;
2293 rel_hdr = &elf_section_data (sec)->rel_hdr;
2295 /* Do the actual relocation. */
2297 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2298 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2299 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2300 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2301 else
2302 BFD_ASSERT (0);
2305 static void
2306 mips_elf64_write_rel (abfd, sec, rel_hdr, count, data)
2307 bfd *abfd;
2308 asection *sec;
2309 Elf_Internal_Shdr *rel_hdr;
2310 int *count;
2311 PTR data;
2313 bfd_boolean *failedp = (bfd_boolean *) data;
2314 Elf64_Mips_External_Rel *ext_rel;
2315 unsigned int idx;
2316 asymbol *last_sym = 0;
2317 int last_sym_idx = 0;
2319 rel_hdr->sh_size = (bfd_vma)(rel_hdr->sh_entsize * *count);
2320 rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
2321 if (rel_hdr->contents == NULL)
2323 *failedp = TRUE;
2324 return;
2327 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2328 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2330 arelent *ptr;
2331 Elf64_Mips_Internal_Rela int_rel;
2332 asymbol *sym;
2333 int n;
2334 unsigned int i;
2336 ptr = sec->orelocation[idx];
2338 /* The address of an ELF reloc is section relative for an object
2339 file, and absolute for an executable file or shared library.
2340 The address of a BFD reloc is always section relative. */
2341 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2342 int_rel.r_offset = ptr->address;
2343 else
2344 int_rel.r_offset = ptr->address + sec->vma;
2346 sym = *ptr->sym_ptr_ptr;
2347 if (sym == last_sym)
2348 n = last_sym_idx;
2349 else
2351 last_sym = sym;
2352 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2353 if (n < 0)
2355 *failedp = TRUE;
2356 return;
2358 last_sym_idx = n;
2361 int_rel.r_sym = n;
2362 int_rel.r_ssym = RSS_UNDEF;
2364 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2365 && ! _bfd_elf_validate_reloc (abfd, ptr))
2367 *failedp = TRUE;
2368 return;
2371 int_rel.r_type = ptr->howto->type;
2372 int_rel.r_type2 = (int) R_MIPS_NONE;
2373 int_rel.r_type3 = (int) R_MIPS_NONE;
2375 for (i = 0; i < 2; i++)
2377 arelent *r;
2379 if (idx + 1 >= sec->reloc_count)
2380 break;
2381 r = sec->orelocation[idx + 1];
2382 if (r->address != ptr->address
2383 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2384 || (*r->sym_ptr_ptr)->value != 0)
2385 break;
2387 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2389 if (i == 0)
2390 int_rel.r_type2 = r->howto->type;
2391 else
2392 int_rel.r_type3 = r->howto->type;
2394 ++idx;
2397 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2400 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2401 == *count);
2404 static void
2405 mips_elf64_write_rela (abfd, sec, rela_hdr, count, data)
2406 bfd *abfd;
2407 asection *sec;
2408 Elf_Internal_Shdr *rela_hdr;
2409 int *count;
2410 PTR data;
2412 bfd_boolean *failedp = (bfd_boolean *) data;
2413 Elf64_Mips_External_Rela *ext_rela;
2414 unsigned int idx;
2415 asymbol *last_sym = 0;
2416 int last_sym_idx = 0;
2418 rela_hdr->sh_size = (bfd_vma)(rela_hdr->sh_entsize * *count);
2419 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
2420 if (rela_hdr->contents == NULL)
2422 *failedp = TRUE;
2423 return;
2426 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2427 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2429 arelent *ptr;
2430 Elf64_Mips_Internal_Rela int_rela;
2431 asymbol *sym;
2432 int n;
2433 unsigned int i;
2435 ptr = sec->orelocation[idx];
2437 /* The address of an ELF reloc is section relative for an object
2438 file, and absolute for an executable file or shared library.
2439 The address of a BFD reloc is always section relative. */
2440 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2441 int_rela.r_offset = ptr->address;
2442 else
2443 int_rela.r_offset = ptr->address + sec->vma;
2445 sym = *ptr->sym_ptr_ptr;
2446 if (sym == last_sym)
2447 n = last_sym_idx;
2448 else
2450 last_sym = sym;
2451 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2452 if (n < 0)
2454 *failedp = TRUE;
2455 return;
2457 last_sym_idx = n;
2460 int_rela.r_sym = n;
2461 int_rela.r_addend = ptr->addend;
2462 int_rela.r_ssym = RSS_UNDEF;
2464 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2465 && ! _bfd_elf_validate_reloc (abfd, ptr))
2467 *failedp = TRUE;
2468 return;
2471 int_rela.r_type = ptr->howto->type;
2472 int_rela.r_type2 = (int) R_MIPS_NONE;
2473 int_rela.r_type3 = (int) R_MIPS_NONE;
2475 for (i = 0; i < 2; i++)
2477 arelent *r;
2479 if (idx + 1 >= sec->reloc_count)
2480 break;
2481 r = sec->orelocation[idx + 1];
2482 if (r->address != ptr->address
2483 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2484 || (*r->sym_ptr_ptr)->value != 0)
2485 break;
2487 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2489 if (i == 0)
2490 int_rela.r_type2 = r->howto->type;
2491 else
2492 int_rela.r_type3 = r->howto->type;
2494 ++idx;
2497 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2500 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2501 == *count);
2504 /* Set the right machine number for a MIPS ELF file. */
2506 static bfd_boolean
2507 mips_elf64_object_p (abfd)
2508 bfd *abfd;
2510 unsigned long mach;
2512 /* Irix 6 is broken. Object file symbol tables are not always
2513 sorted correctly such that local symbols precede global symbols,
2514 and the sh_info field in the symbol table is not always right. */
2515 if (elf64_mips_irix_compat (abfd) != ict_none)
2516 elf_bad_symtab (abfd) = TRUE;
2518 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2519 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2520 return TRUE;
2523 /* Depending on the target vector we generate some version of Irix
2524 executables or "normal" MIPS ELF ABI executables. */
2525 static irix_compat_t
2526 elf64_mips_irix_compat (abfd)
2527 bfd *abfd;
2529 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2530 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2531 return ict_irix6;
2532 else
2533 return ict_none;
2536 /* Support for core dump NOTE sections. */
2537 static bfd_boolean
2538 elf64_mips_grok_prstatus (abfd, note)
2539 bfd *abfd;
2540 Elf_Internal_Note *note;
2542 int offset;
2543 unsigned int raw_size;
2545 switch (note->descsz)
2547 default:
2548 return FALSE;
2550 case 480: /* Linux/MIPS - N64 kernel */
2551 /* pr_cursig */
2552 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2554 /* pr_pid */
2555 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2557 /* pr_reg */
2558 offset = 112;
2559 raw_size = 360;
2561 break;
2564 /* Make a ".reg/999" section. */
2565 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2566 raw_size, note->descpos + offset);
2569 static bfd_boolean
2570 elf64_mips_grok_psinfo (abfd, note)
2571 bfd *abfd;
2572 Elf_Internal_Note *note;
2574 switch (note->descsz)
2576 default:
2577 return FALSE;
2579 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2580 elf_tdata (abfd)->core_program
2581 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2582 elf_tdata (abfd)->core_command
2583 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2586 /* Note that for some reason, a spurious space is tacked
2587 onto the end of the args in some (at least one anyway)
2588 implementations, so strip it off if it exists. */
2591 char *command = elf_tdata (abfd)->core_command;
2592 int n = strlen (command);
2594 if (0 < n && command[n - 1] == ' ')
2595 command[n - 1] = '\0';
2598 return TRUE;
2601 /* ECOFF swapping routines. These are used when dealing with the
2602 .mdebug section, which is in the ECOFF debugging format. */
2603 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2605 /* Symbol table magic number. */
2606 magicSym2,
2607 /* Alignment of debugging information. E.g., 4. */
2609 /* Sizes of external symbolic information. */
2610 sizeof (struct hdr_ext),
2611 sizeof (struct dnr_ext),
2612 sizeof (struct pdr_ext),
2613 sizeof (struct sym_ext),
2614 sizeof (struct opt_ext),
2615 sizeof (struct fdr_ext),
2616 sizeof (struct rfd_ext),
2617 sizeof (struct ext_ext),
2618 /* Functions to swap in external symbolic data. */
2619 ecoff_swap_hdr_in,
2620 ecoff_swap_dnr_in,
2621 ecoff_swap_pdr_in,
2622 ecoff_swap_sym_in,
2623 ecoff_swap_opt_in,
2624 ecoff_swap_fdr_in,
2625 ecoff_swap_rfd_in,
2626 ecoff_swap_ext_in,
2627 _bfd_ecoff_swap_tir_in,
2628 _bfd_ecoff_swap_rndx_in,
2629 /* Functions to swap out external symbolic data. */
2630 ecoff_swap_hdr_out,
2631 ecoff_swap_dnr_out,
2632 ecoff_swap_pdr_out,
2633 ecoff_swap_sym_out,
2634 ecoff_swap_opt_out,
2635 ecoff_swap_fdr_out,
2636 ecoff_swap_rfd_out,
2637 ecoff_swap_ext_out,
2638 _bfd_ecoff_swap_tir_out,
2639 _bfd_ecoff_swap_rndx_out,
2640 /* Function to read in symbolic data. */
2641 _bfd_mips_elf_read_ecoff_info
2644 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2645 standard ELF. This structure is used to redirect the relocation
2646 handling routines. */
2648 const struct elf_size_info mips_elf64_size_info =
2650 sizeof (Elf64_External_Ehdr),
2651 sizeof (Elf64_External_Phdr),
2652 sizeof (Elf64_External_Shdr),
2653 sizeof (Elf64_Mips_External_Rel),
2654 sizeof (Elf64_Mips_External_Rela),
2655 sizeof (Elf64_External_Sym),
2656 sizeof (Elf64_External_Dyn),
2657 sizeof (Elf_External_Note),
2658 4, /* hash-table entry size */
2659 3, /* internal relocations per external relocations */
2660 64, /* arch_size */
2661 8, /* file_align */
2662 ELFCLASS64,
2663 EV_CURRENT,
2664 bfd_elf64_write_out_phdrs,
2665 bfd_elf64_write_shdrs_and_ehdr,
2666 mips_elf64_write_relocs,
2667 bfd_elf64_swap_symbol_in,
2668 bfd_elf64_swap_symbol_out,
2669 mips_elf64_slurp_reloc_table,
2670 bfd_elf64_slurp_symbol_table,
2671 bfd_elf64_swap_dyn_in,
2672 bfd_elf64_swap_dyn_out,
2673 mips_elf64_be_swap_reloc_in,
2674 mips_elf64_be_swap_reloc_out,
2675 mips_elf64_be_swap_reloca_in,
2676 mips_elf64_be_swap_reloca_out
2679 #define ELF_ARCH bfd_arch_mips
2680 #define ELF_MACHINE_CODE EM_MIPS
2682 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2683 a value of 0x1000, and we are compatible.
2684 FIXME: How does this affect NewABI? */
2685 #define ELF_MAXPAGESIZE 0x1000
2687 #define elf_backend_collect TRUE
2688 #define elf_backend_type_change_ok TRUE
2689 #define elf_backend_can_gc_sections TRUE
2690 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2691 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2692 #define elf_backend_object_p mips_elf64_object_p
2693 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2694 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2695 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2696 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2697 #define elf_backend_section_from_bfd_section \
2698 _bfd_mips_elf_section_from_bfd_section
2699 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2700 #define elf_backend_link_output_symbol_hook \
2701 _bfd_mips_elf_link_output_symbol_hook
2702 #define elf_backend_create_dynamic_sections \
2703 _bfd_mips_elf_create_dynamic_sections
2704 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2705 #define elf_backend_adjust_dynamic_symbol \
2706 _bfd_mips_elf_adjust_dynamic_symbol
2707 #define elf_backend_always_size_sections \
2708 _bfd_mips_elf_always_size_sections
2709 #define elf_backend_size_dynamic_sections \
2710 _bfd_mips_elf_size_dynamic_sections
2711 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2712 #define elf_backend_finish_dynamic_symbol \
2713 _bfd_mips_elf_finish_dynamic_symbol
2714 #define elf_backend_finish_dynamic_sections \
2715 _bfd_mips_elf_finish_dynamic_sections
2716 #define elf_backend_final_write_processing \
2717 _bfd_mips_elf_final_write_processing
2718 #define elf_backend_additional_program_headers \
2719 _bfd_mips_elf_additional_program_headers
2720 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2721 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2722 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2723 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2724 #define elf_backend_ignore_discarded_relocs \
2725 _bfd_mips_elf_ignore_discarded_relocs
2726 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2727 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2728 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2729 #define elf_backend_size_info mips_elf64_size_info
2731 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
2732 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
2734 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2735 #define elf_backend_plt_header_size 0
2737 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2738 work better/work only in RELA, so we default to this. */
2739 #define elf_backend_may_use_rel_p 1
2740 #define elf_backend_may_use_rela_p 1
2741 #define elf_backend_default_use_rela_p 1
2743 #define elf_backend_write_section _bfd_mips_elf_write_section
2745 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2746 MIPS-specific function only applies to IRIX5, which had no 64-bit
2747 ABI. */
2748 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2749 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2750 #define bfd_elf64_bfd_get_relocated_section_contents \
2751 _bfd_elf_mips_get_relocated_section_contents
2752 #define bfd_elf64_bfd_link_hash_table_create \
2753 _bfd_mips_elf_link_hash_table_create
2754 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2755 #define bfd_elf64_bfd_merge_private_bfd_data \
2756 _bfd_mips_elf_merge_private_bfd_data
2757 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2758 #define bfd_elf64_bfd_print_private_bfd_data \
2759 _bfd_mips_elf_print_private_bfd_data
2761 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2763 /* MIPS ELF64 archive functions. */
2764 #define bfd_elf64_archive_functions
2765 extern bfd_boolean bfd_elf64_archive_slurp_armap
2766 PARAMS ((bfd *));
2767 extern bfd_boolean bfd_elf64_archive_write_armap
2768 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
2769 #define bfd_elf64_archive_slurp_extended_name_table \
2770 _bfd_archive_coff_slurp_extended_name_table
2771 #define bfd_elf64_archive_construct_extended_name_table \
2772 _bfd_archive_coff_construct_extended_name_table
2773 #define bfd_elf64_archive_truncate_arname \
2774 _bfd_archive_coff_truncate_arname
2775 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2776 #define bfd_elf64_archive_openr_next_archived_file \
2777 _bfd_archive_coff_openr_next_archived_file
2778 #define bfd_elf64_archive_get_elt_at_index \
2779 _bfd_archive_coff_get_elt_at_index
2780 #define bfd_elf64_archive_generic_stat_arch_elt \
2781 _bfd_archive_coff_generic_stat_arch_elt
2782 #define bfd_elf64_archive_update_armap_timestamp \
2783 _bfd_archive_coff_update_armap_timestamp
2785 /* The SGI style (n)64 NewABI. */
2786 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2787 #define TARGET_LITTLE_NAME "elf64-littlemips"
2788 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2789 #define TARGET_BIG_NAME "elf64-bigmips"
2791 #include "elf64-target.h"
2793 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2795 /* The SYSV-style 'traditional' (n)64 NewABI. */
2796 #undef TARGET_LITTLE_SYM
2797 #undef TARGET_LITTLE_NAME
2798 #undef TARGET_BIG_SYM
2799 #undef TARGET_BIG_NAME
2801 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2802 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2803 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2804 #define TARGET_BIG_NAME "elf64-tradbigmips"
2806 /* Include the target file again for this target. */
2807 #include "elf64-target.h"