* config/tc-arm.c (arm_force_relocation): Return 0 for ARM_IMMEDIATE
[binutils.git] / bfd / elf64-mips.c
blobfda989fde987c4ac9219a2a8285e4d4c3761a3cf
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 *));
129 extern const bfd_target bfd_elf64_bigmips_vec;
130 extern const bfd_target bfd_elf64_littlemips_vec;
132 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
133 from smaller values. Start with zero, widen, *then* decrement. */
134 #define MINUS_ONE (((bfd_vma)0) - 1)
136 /* The number of local .got entries we reserve. */
137 #define MIPS_RESERVED_GOTNO (2)
139 /* The relocation table used for SHT_REL sections. */
141 static reloc_howto_type mips_elf64_howto_table_rel[] =
143 /* No relocation. */
144 HOWTO (R_MIPS_NONE, /* type */
145 0, /* rightshift */
146 0, /* size (0 = byte, 1 = short, 2 = long) */
147 0, /* bitsize */
148 FALSE, /* pc_relative */
149 0, /* bitpos */
150 complain_overflow_dont, /* complain_on_overflow */
151 bfd_elf_generic_reloc, /* special_function */
152 "R_MIPS_NONE", /* name */
153 FALSE, /* partial_inplace */
154 0, /* src_mask */
155 0, /* dst_mask */
156 FALSE), /* pcrel_offset */
158 /* 16 bit relocation. */
159 HOWTO (R_MIPS_16, /* type */
160 0, /* rightshift */
161 2, /* size (0 = byte, 1 = short, 2 = long) */
162 16, /* bitsize */
163 FALSE, /* pc_relative */
164 0, /* bitpos */
165 complain_overflow_signed, /* complain_on_overflow */
166 bfd_elf_generic_reloc, /* special_function */
167 "R_MIPS_16", /* name */
168 TRUE, /* partial_inplace */
169 0x0000ffff, /* src_mask */
170 0x0000ffff, /* dst_mask */
171 FALSE), /* pcrel_offset */
173 /* 32 bit relocation. */
174 HOWTO (R_MIPS_32, /* type */
175 0, /* rightshift */
176 2, /* size (0 = byte, 1 = short, 2 = long) */
177 32, /* bitsize */
178 FALSE, /* pc_relative */
179 0, /* bitpos */
180 complain_overflow_dont, /* complain_on_overflow */
181 bfd_elf_generic_reloc, /* special_function */
182 "R_MIPS_32", /* name */
183 TRUE, /* partial_inplace */
184 0xffffffff, /* src_mask */
185 0xffffffff, /* dst_mask */
186 FALSE), /* pcrel_offset */
188 /* 32 bit symbol relative relocation. */
189 HOWTO (R_MIPS_REL32, /* type */
190 0, /* rightshift */
191 2, /* size (0 = byte, 1 = short, 2 = long) */
192 32, /* bitsize */
193 FALSE, /* pc_relative */
194 0, /* bitpos */
195 complain_overflow_dont, /* complain_on_overflow */
196 bfd_elf_generic_reloc, /* special_function */
197 "R_MIPS_REL32", /* name */
198 TRUE, /* partial_inplace */
199 0xffffffff, /* src_mask */
200 0xffffffff, /* dst_mask */
201 FALSE), /* pcrel_offset */
203 /* 26 bit jump address. */
204 HOWTO (R_MIPS_26, /* type */
205 2, /* rightshift */
206 2, /* size (0 = byte, 1 = short, 2 = long) */
207 26, /* bitsize */
208 FALSE, /* pc_relative */
209 0, /* bitpos */
210 complain_overflow_dont, /* complain_on_overflow */
211 /* This needs complex overflow
212 detection, because the upper 36
213 bits must match the PC + 4. */
214 bfd_elf_generic_reloc, /* special_function */
215 "R_MIPS_26", /* name */
216 TRUE, /* partial_inplace */
217 0x03ffffff, /* src_mask */
218 0x03ffffff, /* dst_mask */
219 FALSE), /* pcrel_offset */
221 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
222 However, the native IRIX6 tools use them, so we try our best. */
224 /* High 16 bits of symbol value. */
225 HOWTO (R_MIPS_HI16, /* type */
226 0, /* rightshift */
227 2, /* size (0 = byte, 1 = short, 2 = long) */
228 16, /* bitsize */
229 FALSE, /* pc_relative */
230 0, /* bitpos */
231 complain_overflow_dont, /* complain_on_overflow */
232 mips_elf64_hi16_reloc, /* special_function */
233 "R_MIPS_HI16", /* name */
234 TRUE, /* partial_inplace */
235 0x0000ffff, /* src_mask */
236 0x0000ffff, /* dst_mask */
237 FALSE), /* pcrel_offset */
239 /* Low 16 bits of symbol value. */
240 HOWTO (R_MIPS_LO16, /* type */
241 0, /* rightshift */
242 2, /* size (0 = byte, 1 = short, 2 = long) */
243 16, /* bitsize */
244 FALSE, /* pc_relative */
245 0, /* bitpos */
246 complain_overflow_dont, /* complain_on_overflow */
247 bfd_elf_generic_reloc, /* special_function */
248 "R_MIPS_LO16", /* name */
249 TRUE, /* partial_inplace */
250 0x0000ffff, /* src_mask */
251 0x0000ffff, /* dst_mask */
252 FALSE), /* pcrel_offset */
254 /* GP relative reference. */
255 HOWTO (R_MIPS_GPREL16, /* type */
256 0, /* rightshift */
257 2, /* size (0 = byte, 1 = short, 2 = long) */
258 16, /* bitsize */
259 FALSE, /* pc_relative */
260 0, /* bitpos */
261 complain_overflow_signed, /* complain_on_overflow */
262 mips_elf64_gprel16_reloc, /* special_function */
263 "R_MIPS_GPREL16", /* name */
264 TRUE, /* partial_inplace */
265 0x0000ffff, /* src_mask */
266 0x0000ffff, /* dst_mask */
267 FALSE), /* pcrel_offset */
269 /* Reference to literal section. */
270 HOWTO (R_MIPS_LITERAL, /* type */
271 0, /* rightshift */
272 2, /* size (0 = byte, 1 = short, 2 = long) */
273 16, /* bitsize */
274 FALSE, /* pc_relative */
275 0, /* bitpos */
276 complain_overflow_signed, /* complain_on_overflow */
277 mips_elf64_literal_reloc, /* special_function */
278 "R_MIPS_LITERAL", /* name */
279 TRUE, /* partial_inplace */
280 0x0000ffff, /* src_mask */
281 0x0000ffff, /* dst_mask */
282 FALSE), /* pcrel_offset */
284 /* Reference to global offset table. */
285 HOWTO (R_MIPS_GOT16, /* type */
286 0, /* rightshift */
287 2, /* size (0 = byte, 1 = short, 2 = long) */
288 16, /* bitsize */
289 FALSE, /* pc_relative */
290 0, /* bitpos */
291 complain_overflow_signed, /* complain_on_overflow */
292 mips_elf64_got16_reloc, /* special_function */
293 "R_MIPS_GOT16", /* name */
294 TRUE, /* partial_inplace */
295 0x0000ffff, /* src_mask */
296 0x0000ffff, /* dst_mask */
297 FALSE), /* pcrel_offset */
299 /* 16 bit PC relative reference. */
300 HOWTO (R_MIPS_PC16, /* type */
301 0, /* rightshift */
302 2, /* size (0 = byte, 1 = short, 2 = long) */
303 16, /* bitsize */
304 TRUE, /* pc_relative */
305 0, /* bitpos */
306 complain_overflow_signed, /* complain_on_overflow */
307 bfd_elf_generic_reloc, /* special_function */
308 "R_MIPS_PC16", /* name */
309 TRUE, /* partial_inplace */
310 0x0000ffff, /* src_mask */
311 0x0000ffff, /* dst_mask */
312 TRUE), /* pcrel_offset */
314 /* 16 bit call through global offset table. */
315 HOWTO (R_MIPS_CALL16, /* type */
316 0, /* rightshift */
317 2, /* size (0 = byte, 1 = short, 2 = long) */
318 16, /* bitsize */
319 FALSE, /* pc_relative */
320 0, /* bitpos */
321 complain_overflow_signed, /* complain_on_overflow */
322 bfd_elf_generic_reloc, /* special_function */
323 "R_MIPS_CALL16", /* name */
324 TRUE, /* partial_inplace */
325 0x0000ffff, /* src_mask */
326 0x0000ffff, /* dst_mask */
327 FALSE), /* pcrel_offset */
329 /* 32 bit GP relative reference. */
330 HOWTO (R_MIPS_GPREL32, /* type */
331 0, /* rightshift */
332 2, /* size (0 = byte, 1 = short, 2 = long) */
333 32, /* bitsize */
334 FALSE, /* pc_relative */
335 0, /* bitpos */
336 complain_overflow_dont, /* complain_on_overflow */
337 mips_elf64_gprel32_reloc, /* special_function */
338 "R_MIPS_GPREL32", /* name */
339 TRUE, /* partial_inplace */
340 0xffffffff, /* src_mask */
341 0xffffffff, /* dst_mask */
342 FALSE), /* pcrel_offset */
344 EMPTY_HOWTO (13),
345 EMPTY_HOWTO (14),
346 EMPTY_HOWTO (15),
348 /* A 5 bit shift field. */
349 HOWTO (R_MIPS_SHIFT5, /* type */
350 0, /* rightshift */
351 2, /* size (0 = byte, 1 = short, 2 = long) */
352 5, /* bitsize */
353 FALSE, /* pc_relative */
354 6, /* bitpos */
355 complain_overflow_bitfield, /* complain_on_overflow */
356 bfd_elf_generic_reloc, /* special_function */
357 "R_MIPS_SHIFT5", /* name */
358 TRUE, /* partial_inplace */
359 0x000007c0, /* src_mask */
360 0x000007c0, /* dst_mask */
361 FALSE), /* pcrel_offset */
363 /* A 6 bit shift field. */
364 HOWTO (R_MIPS_SHIFT6, /* type */
365 0, /* rightshift */
366 2, /* size (0 = byte, 1 = short, 2 = long) */
367 6, /* bitsize */
368 FALSE, /* pc_relative */
369 6, /* bitpos */
370 complain_overflow_bitfield, /* complain_on_overflow */
371 mips_elf64_shift6_reloc, /* special_function */
372 "R_MIPS_SHIFT6", /* name */
373 TRUE, /* partial_inplace */
374 0x000007c4, /* src_mask */
375 0x000007c4, /* dst_mask */
376 FALSE), /* pcrel_offset */
378 /* 64 bit relocation. */
379 HOWTO (R_MIPS_64, /* type */
380 0, /* rightshift */
381 4, /* size (0 = byte, 1 = short, 2 = long) */
382 64, /* bitsize */
383 FALSE, /* pc_relative */
384 0, /* bitpos */
385 complain_overflow_dont, /* complain_on_overflow */
386 bfd_elf_generic_reloc, /* special_function */
387 "R_MIPS_64", /* name */
388 TRUE, /* partial_inplace */
389 MINUS_ONE, /* src_mask */
390 MINUS_ONE, /* dst_mask */
391 FALSE), /* pcrel_offset */
393 /* Displacement in the global offset table. */
394 HOWTO (R_MIPS_GOT_DISP, /* type */
395 0, /* rightshift */
396 2, /* size (0 = byte, 1 = short, 2 = long) */
397 16, /* bitsize */
398 FALSE, /* pc_relative */
399 0, /* bitpos */
400 complain_overflow_signed, /* complain_on_overflow */
401 bfd_elf_generic_reloc, /* special_function */
402 "R_MIPS_GOT_DISP", /* name */
403 TRUE, /* partial_inplace */
404 0x0000ffff, /* src_mask */
405 0x0000ffff, /* dst_mask */
406 FALSE), /* pcrel_offset */
408 /* Displacement to page pointer in the global offset table. */
409 HOWTO (R_MIPS_GOT_PAGE, /* type */
410 0, /* rightshift */
411 2, /* size (0 = byte, 1 = short, 2 = long) */
412 16, /* bitsize */
413 FALSE, /* pc_relative */
414 0, /* bitpos */
415 complain_overflow_signed, /* complain_on_overflow */
416 bfd_elf_generic_reloc, /* special_function */
417 "R_MIPS_GOT_PAGE", /* name */
418 TRUE, /* partial_inplace */
419 0x0000ffff, /* src_mask */
420 0x0000ffff, /* dst_mask */
421 FALSE), /* pcrel_offset */
423 /* Offset from page pointer in the global offset table. */
424 HOWTO (R_MIPS_GOT_OFST, /* type */
425 0, /* rightshift */
426 2, /* size (0 = byte, 1 = short, 2 = long) */
427 16, /* bitsize */
428 FALSE, /* pc_relative */
429 0, /* bitpos */
430 complain_overflow_signed, /* complain_on_overflow */
431 bfd_elf_generic_reloc, /* special_function */
432 "R_MIPS_GOT_OFST", /* name */
433 TRUE, /* partial_inplace */
434 0x0000ffff, /* src_mask */
435 0x0000ffff, /* dst_mask */
436 FALSE), /* pcrel_offset */
438 /* High 16 bits of displacement in global offset table. */
439 HOWTO (R_MIPS_GOT_HI16, /* type */
440 0, /* rightshift */
441 2, /* size (0 = byte, 1 = short, 2 = long) */
442 16, /* bitsize */
443 FALSE, /* pc_relative */
444 0, /* bitpos */
445 complain_overflow_dont, /* complain_on_overflow */
446 bfd_elf_generic_reloc, /* special_function */
447 "R_MIPS_GOT_HI16", /* name */
448 TRUE, /* partial_inplace */
449 0x0000ffff, /* src_mask */
450 0x0000ffff, /* dst_mask */
451 FALSE), /* pcrel_offset */
453 /* Low 16 bits of displacement in global offset table. */
454 HOWTO (R_MIPS_GOT_LO16, /* type */
455 0, /* rightshift */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
457 16, /* bitsize */
458 FALSE, /* pc_relative */
459 0, /* bitpos */
460 complain_overflow_dont, /* complain_on_overflow */
461 bfd_elf_generic_reloc, /* special_function */
462 "R_MIPS_GOT_LO16", /* name */
463 TRUE, /* partial_inplace */
464 0x0000ffff, /* src_mask */
465 0x0000ffff, /* dst_mask */
466 FALSE), /* pcrel_offset */
468 /* 64 bit substraction. */
469 HOWTO (R_MIPS_SUB, /* type */
470 0, /* rightshift */
471 4, /* size (0 = byte, 1 = short, 2 = long) */
472 64, /* bitsize */
473 FALSE, /* pc_relative */
474 0, /* bitpos */
475 complain_overflow_dont, /* complain_on_overflow */
476 bfd_elf_generic_reloc, /* special_function */
477 "R_MIPS_SUB", /* name */
478 TRUE, /* partial_inplace */
479 MINUS_ONE, /* src_mask */
480 MINUS_ONE, /* dst_mask */
481 FALSE), /* pcrel_offset */
483 /* Insert the addend as an instruction. */
484 /* FIXME: Not handled correctly. */
485 HOWTO (R_MIPS_INSERT_A, /* type */
486 0, /* rightshift */
487 2, /* size (0 = byte, 1 = short, 2 = long) */
488 32, /* bitsize */
489 FALSE, /* pc_relative */
490 0, /* bitpos */
491 complain_overflow_dont, /* complain_on_overflow */
492 bfd_elf_generic_reloc, /* special_function */
493 "R_MIPS_INSERT_A", /* name */
494 TRUE, /* partial_inplace */
495 0xffffffff, /* src_mask */
496 0xffffffff, /* dst_mask */
497 FALSE), /* pcrel_offset */
499 /* Insert the addend as an instruction, and change all relocations
500 to refer to the old instruction at the address. */
501 /* FIXME: Not handled correctly. */
502 HOWTO (R_MIPS_INSERT_B, /* type */
503 0, /* rightshift */
504 2, /* size (0 = byte, 1 = short, 2 = long) */
505 32, /* bitsize */
506 FALSE, /* pc_relative */
507 0, /* bitpos */
508 complain_overflow_dont, /* complain_on_overflow */
509 bfd_elf_generic_reloc, /* special_function */
510 "R_MIPS_INSERT_B", /* name */
511 TRUE, /* partial_inplace */
512 0xffffffff, /* src_mask */
513 0xffffffff, /* dst_mask */
514 FALSE), /* pcrel_offset */
516 /* Delete a 32 bit instruction. */
517 /* FIXME: Not handled correctly. */
518 HOWTO (R_MIPS_DELETE, /* type */
519 0, /* rightshift */
520 2, /* size (0 = byte, 1 = short, 2 = long) */
521 32, /* bitsize */
522 FALSE, /* pc_relative */
523 0, /* bitpos */
524 complain_overflow_dont, /* complain_on_overflow */
525 bfd_elf_generic_reloc, /* special_function */
526 "R_MIPS_DELETE", /* name */
527 TRUE, /* partial_inplace */
528 0xffffffff, /* src_mask */
529 0xffffffff, /* dst_mask */
530 FALSE), /* pcrel_offset */
532 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
533 We don't, because
534 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
535 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
536 fallable heuristics.
537 b) No other NewABI toolchain actually emits such relocations. */
538 EMPTY_HOWTO (R_MIPS_HIGHER),
539 EMPTY_HOWTO (R_MIPS_HIGHEST),
541 /* High 16 bits of displacement in global offset table. */
542 HOWTO (R_MIPS_CALL_HI16, /* type */
543 0, /* rightshift */
544 2, /* size (0 = byte, 1 = short, 2 = long) */
545 16, /* bitsize */
546 FALSE, /* pc_relative */
547 0, /* bitpos */
548 complain_overflow_dont, /* complain_on_overflow */
549 bfd_elf_generic_reloc, /* special_function */
550 "R_MIPS_CALL_HI16", /* name */
551 TRUE, /* partial_inplace */
552 0x0000ffff, /* src_mask */
553 0x0000ffff, /* dst_mask */
554 FALSE), /* pcrel_offset */
556 /* Low 16 bits of displacement in global offset table. */
557 HOWTO (R_MIPS_CALL_LO16, /* type */
558 0, /* rightshift */
559 2, /* size (0 = byte, 1 = short, 2 = long) */
560 16, /* bitsize */
561 FALSE, /* pc_relative */
562 0, /* bitpos */
563 complain_overflow_dont, /* complain_on_overflow */
564 bfd_elf_generic_reloc, /* special_function */
565 "R_MIPS_CALL_LO16", /* name */
566 TRUE, /* partial_inplace */
567 0x0000ffff, /* src_mask */
568 0x0000ffff, /* dst_mask */
569 FALSE), /* pcrel_offset */
571 /* Section displacement, used by an associated event location section. */
572 HOWTO (R_MIPS_SCN_DISP, /* type */
573 0, /* rightshift */
574 2, /* size (0 = byte, 1 = short, 2 = long) */
575 32, /* bitsize */
576 FALSE, /* pc_relative */
577 0, /* bitpos */
578 complain_overflow_dont, /* complain_on_overflow */
579 bfd_elf_generic_reloc, /* special_function */
580 "R_MIPS_SCN_DISP", /* name */
581 TRUE, /* partial_inplace */
582 0xffffffff, /* src_mask */
583 0xffffffff, /* dst_mask */
584 FALSE), /* pcrel_offset */
586 HOWTO (R_MIPS_REL16, /* type */
587 0, /* rightshift */
588 1, /* size (0 = byte, 1 = short, 2 = long) */
589 16, /* bitsize */
590 FALSE, /* pc_relative */
591 0, /* bitpos */
592 complain_overflow_signed, /* complain_on_overflow */
593 bfd_elf_generic_reloc, /* special_function */
594 "R_MIPS_REL16", /* name */
595 TRUE, /* partial_inplace */
596 0xffff, /* src_mask */
597 0xffff, /* dst_mask */
598 FALSE), /* pcrel_offset */
600 /* These two are obsolete. */
601 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
602 EMPTY_HOWTO (R_MIPS_PJUMP),
604 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
605 It must be used for multigot GOT's (and only there). */
606 HOWTO (R_MIPS_RELGOT, /* type */
607 0, /* rightshift */
608 2, /* size (0 = byte, 1 = short, 2 = long) */
609 32, /* bitsize */
610 FALSE, /* pc_relative */
611 0, /* bitpos */
612 complain_overflow_dont, /* complain_on_overflow */
613 bfd_elf_generic_reloc, /* special_function */
614 "R_MIPS_RELGOT", /* name */
615 TRUE, /* partial_inplace */
616 0xffffffff, /* src_mask */
617 0xffffffff, /* dst_mask */
618 FALSE), /* pcrel_offset */
620 /* Protected jump conversion. This is an optimization hint. No
621 relocation is required for correctness. */
622 HOWTO (R_MIPS_JALR, /* type */
623 0, /* rightshift */
624 2, /* size (0 = byte, 1 = short, 2 = long) */
625 32, /* bitsize */
626 FALSE, /* pc_relative */
627 0, /* bitpos */
628 complain_overflow_dont, /* complain_on_overflow */
629 bfd_elf_generic_reloc, /* special_function */
630 "R_MIPS_JALR", /* name */
631 FALSE, /* partial_inplace */
632 0, /* src_mask */
633 0x00000000, /* dst_mask */
634 FALSE), /* pcrel_offset */
637 /* The relocation table used for SHT_RELA sections. */
639 static reloc_howto_type mips_elf64_howto_table_rela[] =
641 /* No relocation. */
642 HOWTO (R_MIPS_NONE, /* type */
643 0, /* rightshift */
644 0, /* size (0 = byte, 1 = short, 2 = long) */
645 0, /* bitsize */
646 FALSE, /* pc_relative */
647 0, /* bitpos */
648 complain_overflow_dont, /* complain_on_overflow */
649 bfd_elf_generic_reloc, /* special_function */
650 "R_MIPS_NONE", /* name */
651 FALSE, /* partial_inplace */
652 0, /* src_mask */
653 0, /* dst_mask */
654 FALSE), /* pcrel_offset */
656 /* 16 bit relocation. */
657 HOWTO (R_MIPS_16, /* type */
658 0, /* rightshift */
659 2, /* size (0 = byte, 1 = short, 2 = long) */
660 16, /* bitsize */
661 FALSE, /* pc_relative */
662 0, /* bitpos */
663 complain_overflow_signed, /* complain_on_overflow */
664 bfd_elf_generic_reloc, /* special_function */
665 "R_MIPS_16", /* name */
666 FALSE, /* partial_inplace */
667 0, /* src_mask */
668 0x0000ffff, /* dst_mask */
669 FALSE), /* pcrel_offset */
671 /* 32 bit relocation. */
672 HOWTO (R_MIPS_32, /* type */
673 0, /* rightshift */
674 2, /* size (0 = byte, 1 = short, 2 = long) */
675 32, /* bitsize */
676 FALSE, /* pc_relative */
677 0, /* bitpos */
678 complain_overflow_dont, /* complain_on_overflow */
679 bfd_elf_generic_reloc, /* special_function */
680 "R_MIPS_32", /* name */
681 FALSE, /* partial_inplace */
682 0, /* src_mask */
683 0xffffffff, /* dst_mask */
684 FALSE), /* pcrel_offset */
686 /* 32 bit symbol relative relocation. */
687 HOWTO (R_MIPS_REL32, /* type */
688 0, /* rightshift */
689 2, /* size (0 = byte, 1 = short, 2 = long) */
690 32, /* bitsize */
691 FALSE, /* pc_relative */
692 0, /* bitpos */
693 complain_overflow_dont, /* complain_on_overflow */
694 bfd_elf_generic_reloc, /* special_function */
695 "R_MIPS_REL32", /* name */
696 FALSE, /* partial_inplace */
697 0, /* src_mask */
698 0xffffffff, /* dst_mask */
699 FALSE), /* pcrel_offset */
701 /* 26 bit jump address. */
702 HOWTO (R_MIPS_26, /* type */
703 2, /* rightshift */
704 2, /* size (0 = byte, 1 = short, 2 = long) */
705 26, /* bitsize */
706 FALSE, /* pc_relative */
707 0, /* bitpos */
708 complain_overflow_dont, /* complain_on_overflow */
709 /* This needs complex overflow
710 detection, because the upper 36
711 bits must match the PC + 4. */
712 bfd_elf_generic_reloc, /* special_function */
713 "R_MIPS_26", /* name */
714 FALSE, /* partial_inplace */
715 0, /* src_mask */
716 0x03ffffff, /* dst_mask */
717 FALSE), /* pcrel_offset */
719 /* High 16 bits of symbol value. */
720 HOWTO (R_MIPS_HI16, /* type */
721 0, /* rightshift */
722 2, /* size (0 = byte, 1 = short, 2 = long) */
723 16, /* bitsize */
724 FALSE, /* pc_relative */
725 0, /* bitpos */
726 complain_overflow_dont, /* complain_on_overflow */
727 bfd_elf_generic_reloc, /* special_function */
728 "R_MIPS_HI16", /* name */
729 FALSE, /* partial_inplace */
730 0, /* src_mask */
731 0x0000ffff, /* dst_mask */
732 FALSE), /* pcrel_offset */
734 /* Low 16 bits of symbol value. */
735 HOWTO (R_MIPS_LO16, /* type */
736 0, /* rightshift */
737 2, /* size (0 = byte, 1 = short, 2 = long) */
738 16, /* bitsize */
739 FALSE, /* pc_relative */
740 0, /* bitpos */
741 complain_overflow_dont, /* complain_on_overflow */
742 bfd_elf_generic_reloc, /* special_function */
743 "R_MIPS_LO16", /* name */
744 FALSE, /* partial_inplace */
745 0, /* src_mask */
746 0x0000ffff, /* dst_mask */
747 FALSE), /* pcrel_offset */
749 /* GP relative reference. */
750 HOWTO (R_MIPS_GPREL16, /* type */
751 0, /* rightshift */
752 2, /* size (0 = byte, 1 = short, 2 = long) */
753 16, /* bitsize */
754 FALSE, /* pc_relative */
755 0, /* bitpos */
756 complain_overflow_signed, /* complain_on_overflow */
757 mips_elf64_gprel16_reloc, /* special_function */
758 "R_MIPS_GPREL16", /* name */
759 FALSE, /* partial_inplace */
760 0, /* src_mask */
761 0x0000ffff, /* dst_mask */
762 FALSE), /* pcrel_offset */
764 /* Reference to literal section. */
765 HOWTO (R_MIPS_LITERAL, /* type */
766 0, /* rightshift */
767 2, /* size (0 = byte, 1 = short, 2 = long) */
768 16, /* bitsize */
769 FALSE, /* pc_relative */
770 0, /* bitpos */
771 complain_overflow_signed, /* complain_on_overflow */
772 mips_elf64_literal_reloc, /* special_function */
773 "R_MIPS_LITERAL", /* name */
774 FALSE, /* partial_inplace */
775 0, /* src_mask */
776 0x0000ffff, /* dst_mask */
777 FALSE), /* pcrel_offset */
779 /* Reference to global offset table. */
780 HOWTO (R_MIPS_GOT16, /* type */
781 0, /* rightshift */
782 2, /* size (0 = byte, 1 = short, 2 = long) */
783 16, /* bitsize */
784 FALSE, /* pc_relative */
785 0, /* bitpos */
786 complain_overflow_signed, /* complain_on_overflow */
787 mips_elf64_got16_reloc, /* special_function */
788 "R_MIPS_GOT16", /* name */
789 FALSE, /* partial_inplace */
790 0, /* src_mask */
791 0x0000ffff, /* dst_mask */
792 FALSE), /* pcrel_offset */
794 /* 16 bit PC relative reference. */
795 HOWTO (R_MIPS_PC16, /* type */
796 0, /* rightshift */
797 2, /* size (0 = byte, 1 = short, 2 = long) */
798 16, /* bitsize */
799 TRUE, /* pc_relative */
800 0, /* bitpos */
801 complain_overflow_signed, /* complain_on_overflow */
802 bfd_elf_generic_reloc, /* special_function */
803 "R_MIPS_PC16", /* name */
804 FALSE, /* partial_inplace */
805 0, /* src_mask */
806 0x0000ffff, /* dst_mask */
807 TRUE), /* pcrel_offset */
809 /* 16 bit call through global offset table. */
810 HOWTO (R_MIPS_CALL16, /* type */
811 0, /* rightshift */
812 2, /* size (0 = byte, 1 = short, 2 = long) */
813 16, /* bitsize */
814 FALSE, /* pc_relative */
815 0, /* bitpos */
816 complain_overflow_signed, /* complain_on_overflow */
817 bfd_elf_generic_reloc, /* special_function */
818 "R_MIPS_CALL16", /* name */
819 FALSE, /* partial_inplace */
820 0, /* src_mask */
821 0x0000ffff, /* dst_mask */
822 FALSE), /* pcrel_offset */
824 /* 32 bit GP relative reference. */
825 HOWTO (R_MIPS_GPREL32, /* type */
826 0, /* rightshift */
827 2, /* size (0 = byte, 1 = short, 2 = long) */
828 32, /* bitsize */
829 FALSE, /* pc_relative */
830 0, /* bitpos */
831 complain_overflow_dont, /* complain_on_overflow */
832 mips_elf64_gprel32_reloc, /* special_function */
833 "R_MIPS_GPREL32", /* name */
834 FALSE, /* partial_inplace */
835 0, /* src_mask */
836 0xffffffff, /* dst_mask */
837 FALSE), /* pcrel_offset */
839 EMPTY_HOWTO (13),
840 EMPTY_HOWTO (14),
841 EMPTY_HOWTO (15),
843 /* A 5 bit shift field. */
844 HOWTO (R_MIPS_SHIFT5, /* type */
845 0, /* rightshift */
846 2, /* size (0 = byte, 1 = short, 2 = long) */
847 5, /* bitsize */
848 FALSE, /* pc_relative */
849 6, /* bitpos */
850 complain_overflow_bitfield, /* complain_on_overflow */
851 bfd_elf_generic_reloc, /* special_function */
852 "R_MIPS_SHIFT5", /* name */
853 FALSE, /* partial_inplace */
854 0, /* src_mask */
855 0x000007c0, /* dst_mask */
856 FALSE), /* pcrel_offset */
858 /* A 6 bit shift field. */
859 HOWTO (R_MIPS_SHIFT6, /* type */
860 0, /* rightshift */
861 2, /* size (0 = byte, 1 = short, 2 = long) */
862 6, /* bitsize */
863 FALSE, /* pc_relative */
864 6, /* bitpos */
865 complain_overflow_bitfield, /* complain_on_overflow */
866 mips_elf64_shift6_reloc, /* special_function */
867 "R_MIPS_SHIFT6", /* name */
868 FALSE, /* partial_inplace */
869 0, /* src_mask */
870 0x000007c4, /* dst_mask */
871 FALSE), /* pcrel_offset */
873 /* 64 bit relocation. */
874 HOWTO (R_MIPS_64, /* type */
875 0, /* rightshift */
876 4, /* size (0 = byte, 1 = short, 2 = long) */
877 64, /* bitsize */
878 FALSE, /* pc_relative */
879 0, /* bitpos */
880 complain_overflow_dont, /* complain_on_overflow */
881 bfd_elf_generic_reloc, /* special_function */
882 "R_MIPS_64", /* name */
883 FALSE, /* partial_inplace */
884 0, /* src_mask */
885 MINUS_ONE, /* dst_mask */
886 FALSE), /* pcrel_offset */
888 /* Displacement in the global offset table. */
889 HOWTO (R_MIPS_GOT_DISP, /* type */
890 0, /* rightshift */
891 2, /* size (0 = byte, 1 = short, 2 = long) */
892 16, /* bitsize */
893 FALSE, /* pc_relative */
894 0, /* bitpos */
895 complain_overflow_signed, /* complain_on_overflow */
896 bfd_elf_generic_reloc, /* special_function */
897 "R_MIPS_GOT_DISP", /* name */
898 FALSE, /* partial_inplace */
899 0, /* src_mask */
900 0x0000ffff, /* dst_mask */
901 FALSE), /* pcrel_offset */
903 /* Displacement to page pointer in the global offset table. */
904 HOWTO (R_MIPS_GOT_PAGE, /* type */
905 0, /* rightshift */
906 2, /* size (0 = byte, 1 = short, 2 = long) */
907 16, /* bitsize */
908 FALSE, /* pc_relative */
909 0, /* bitpos */
910 complain_overflow_signed, /* complain_on_overflow */
911 bfd_elf_generic_reloc, /* special_function */
912 "R_MIPS_GOT_PAGE", /* name */
913 FALSE, /* partial_inplace */
914 0, /* src_mask */
915 0x0000ffff, /* dst_mask */
916 FALSE), /* pcrel_offset */
918 /* Offset from page pointer in the global offset table. */
919 HOWTO (R_MIPS_GOT_OFST, /* type */
920 0, /* rightshift */
921 2, /* size (0 = byte, 1 = short, 2 = long) */
922 16, /* bitsize */
923 FALSE, /* pc_relative */
924 0, /* bitpos */
925 complain_overflow_signed, /* complain_on_overflow */
926 bfd_elf_generic_reloc, /* special_function */
927 "R_MIPS_GOT_OFST", /* name */
928 FALSE, /* partial_inplace */
929 0, /* src_mask */
930 0x0000ffff, /* dst_mask */
931 FALSE), /* pcrel_offset */
933 /* High 16 bits of displacement in global offset table. */
934 HOWTO (R_MIPS_GOT_HI16, /* type */
935 0, /* rightshift */
936 2, /* size (0 = byte, 1 = short, 2 = long) */
937 16, /* bitsize */
938 FALSE, /* pc_relative */
939 0, /* bitpos */
940 complain_overflow_dont, /* complain_on_overflow */
941 bfd_elf_generic_reloc, /* special_function */
942 "R_MIPS_GOT_HI16", /* name */
943 FALSE, /* partial_inplace */
944 0, /* src_mask */
945 0x0000ffff, /* dst_mask */
946 FALSE), /* pcrel_offset */
948 /* Low 16 bits of displacement in global offset table. */
949 HOWTO (R_MIPS_GOT_LO16, /* type */
950 0, /* rightshift */
951 2, /* size (0 = byte, 1 = short, 2 = long) */
952 16, /* bitsize */
953 FALSE, /* pc_relative */
954 0, /* bitpos */
955 complain_overflow_dont, /* complain_on_overflow */
956 bfd_elf_generic_reloc, /* special_function */
957 "R_MIPS_GOT_LO16", /* name */
958 FALSE, /* partial_inplace */
959 0, /* src_mask */
960 0x0000ffff, /* dst_mask */
961 FALSE), /* pcrel_offset */
963 /* 64 bit substraction. */
964 HOWTO (R_MIPS_SUB, /* type */
965 0, /* rightshift */
966 4, /* size (0 = byte, 1 = short, 2 = long) */
967 64, /* bitsize */
968 FALSE, /* pc_relative */
969 0, /* bitpos */
970 complain_overflow_dont, /* complain_on_overflow */
971 bfd_elf_generic_reloc, /* special_function */
972 "R_MIPS_SUB", /* name */
973 FALSE, /* partial_inplace */
974 0, /* src_mask */
975 MINUS_ONE, /* dst_mask */
976 FALSE), /* pcrel_offset */
978 /* Insert the addend as an instruction. */
979 /* FIXME: Not handled correctly. */
980 HOWTO (R_MIPS_INSERT_A, /* type */
981 0, /* rightshift */
982 2, /* size (0 = byte, 1 = short, 2 = long) */
983 32, /* bitsize */
984 FALSE, /* pc_relative */
985 0, /* bitpos */
986 complain_overflow_dont, /* complain_on_overflow */
987 bfd_elf_generic_reloc, /* special_function */
988 "R_MIPS_INSERT_A", /* name */
989 FALSE, /* partial_inplace */
990 0, /* src_mask */
991 0xffffffff, /* dst_mask */
992 FALSE), /* pcrel_offset */
994 /* Insert the addend as an instruction, and change all relocations
995 to refer to the old instruction at the address. */
996 /* FIXME: Not handled correctly. */
997 HOWTO (R_MIPS_INSERT_B, /* type */
998 0, /* rightshift */
999 2, /* size (0 = byte, 1 = short, 2 = long) */
1000 32, /* bitsize */
1001 FALSE, /* pc_relative */
1002 0, /* bitpos */
1003 complain_overflow_dont, /* complain_on_overflow */
1004 bfd_elf_generic_reloc, /* special_function */
1005 "R_MIPS_INSERT_B", /* name */
1006 FALSE, /* partial_inplace */
1007 0, /* src_mask */
1008 0xffffffff, /* dst_mask */
1009 FALSE), /* pcrel_offset */
1011 /* Delete a 32 bit instruction. */
1012 /* FIXME: Not handled correctly. */
1013 HOWTO (R_MIPS_DELETE, /* type */
1014 0, /* rightshift */
1015 2, /* size (0 = byte, 1 = short, 2 = long) */
1016 32, /* bitsize */
1017 FALSE, /* pc_relative */
1018 0, /* bitpos */
1019 complain_overflow_dont, /* complain_on_overflow */
1020 bfd_elf_generic_reloc, /* special_function */
1021 "R_MIPS_DELETE", /* name */
1022 FALSE, /* partial_inplace */
1023 0, /* src_mask */
1024 0xffffffff, /* dst_mask */
1025 FALSE), /* pcrel_offset */
1027 /* Get the higher value of a 64 bit addend. */
1028 HOWTO (R_MIPS_HIGHER, /* type */
1029 0, /* rightshift */
1030 2, /* size (0 = byte, 1 = short, 2 = long) */
1031 16, /* bitsize */
1032 FALSE, /* pc_relative */
1033 0, /* bitpos */
1034 complain_overflow_dont, /* complain_on_overflow */
1035 bfd_elf_generic_reloc, /* special_function */
1036 "R_MIPS_HIGHER", /* name */
1037 FALSE, /* partial_inplace */
1038 0, /* src_mask */
1039 0x0000ffff, /* dst_mask */
1040 FALSE), /* pcrel_offset */
1042 /* Get the highest value of a 64 bit addend. */
1043 HOWTO (R_MIPS_HIGHEST, /* type */
1044 0, /* rightshift */
1045 2, /* size (0 = byte, 1 = short, 2 = long) */
1046 16, /* bitsize */
1047 FALSE, /* pc_relative */
1048 0, /* bitpos */
1049 complain_overflow_dont, /* complain_on_overflow */
1050 bfd_elf_generic_reloc, /* special_function */
1051 "R_MIPS_HIGHEST", /* name */
1052 FALSE, /* partial_inplace */
1053 0, /* src_mask */
1054 0x0000ffff, /* dst_mask */
1055 FALSE), /* pcrel_offset */
1057 /* High 16 bits of displacement in global offset table. */
1058 HOWTO (R_MIPS_CALL_HI16, /* type */
1059 0, /* rightshift */
1060 2, /* size (0 = byte, 1 = short, 2 = long) */
1061 16, /* bitsize */
1062 FALSE, /* pc_relative */
1063 0, /* bitpos */
1064 complain_overflow_dont, /* complain_on_overflow */
1065 bfd_elf_generic_reloc, /* special_function */
1066 "R_MIPS_CALL_HI16", /* name */
1067 FALSE, /* partial_inplace */
1068 0, /* src_mask */
1069 0x0000ffff, /* dst_mask */
1070 FALSE), /* pcrel_offset */
1072 /* Low 16 bits of displacement in global offset table. */
1073 HOWTO (R_MIPS_CALL_LO16, /* type */
1074 0, /* rightshift */
1075 2, /* size (0 = byte, 1 = short, 2 = long) */
1076 16, /* bitsize */
1077 FALSE, /* pc_relative */
1078 0, /* bitpos */
1079 complain_overflow_dont, /* complain_on_overflow */
1080 bfd_elf_generic_reloc, /* special_function */
1081 "R_MIPS_CALL_LO16", /* name */
1082 FALSE, /* partial_inplace */
1083 0, /* src_mask */
1084 0x0000ffff, /* dst_mask */
1085 FALSE), /* pcrel_offset */
1087 /* Section displacement, used by an associated event location section. */
1088 HOWTO (R_MIPS_SCN_DISP, /* type */
1089 0, /* rightshift */
1090 2, /* size (0 = byte, 1 = short, 2 = long) */
1091 32, /* bitsize */
1092 FALSE, /* pc_relative */
1093 0, /* bitpos */
1094 complain_overflow_dont, /* complain_on_overflow */
1095 bfd_elf_generic_reloc, /* special_function */
1096 "R_MIPS_SCN_DISP", /* name */
1097 FALSE, /* partial_inplace */
1098 0, /* src_mask */
1099 0xffffffff, /* dst_mask */
1100 FALSE), /* pcrel_offset */
1102 HOWTO (R_MIPS_REL16, /* type */
1103 0, /* rightshift */
1104 1, /* size (0 = byte, 1 = short, 2 = long) */
1105 16, /* bitsize */
1106 FALSE, /* pc_relative */
1107 0, /* bitpos */
1108 complain_overflow_signed, /* complain_on_overflow */
1109 bfd_elf_generic_reloc, /* special_function */
1110 "R_MIPS_REL16", /* name */
1111 FALSE, /* partial_inplace */
1112 0, /* src_mask */
1113 0xffff, /* dst_mask */
1114 FALSE), /* pcrel_offset */
1116 /* These two are obsolete. */
1117 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1118 EMPTY_HOWTO (R_MIPS_PJUMP),
1120 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1121 It must be used for multigot GOT's (and only there). */
1122 HOWTO (R_MIPS_RELGOT, /* type */
1123 0, /* rightshift */
1124 2, /* size (0 = byte, 1 = short, 2 = long) */
1125 32, /* bitsize */
1126 FALSE, /* pc_relative */
1127 0, /* bitpos */
1128 complain_overflow_dont, /* complain_on_overflow */
1129 bfd_elf_generic_reloc, /* special_function */
1130 "R_MIPS_RELGOT", /* name */
1131 FALSE, /* partial_inplace */
1132 0, /* src_mask */
1133 0xffffffff, /* dst_mask */
1134 FALSE), /* pcrel_offset */
1136 /* Protected jump conversion. This is an optimization hint. No
1137 relocation is required for correctness. */
1138 HOWTO (R_MIPS_JALR, /* type */
1139 0, /* rightshift */
1140 2, /* size (0 = byte, 1 = short, 2 = long) */
1141 32, /* bitsize */
1142 FALSE, /* pc_relative */
1143 0, /* bitpos */
1144 complain_overflow_dont, /* complain_on_overflow */
1145 bfd_elf_generic_reloc, /* special_function */
1146 "R_MIPS_JALR", /* name */
1147 FALSE, /* partial_inplace */
1148 0, /* src_mask */
1149 0x00000000, /* dst_mask */
1150 FALSE), /* pcrel_offset */
1153 /* The reloc used for the mips16 jump instruction. */
1154 static reloc_howto_type elf_mips16_jump_howto =
1155 HOWTO (R_MIPS16_26, /* type */
1156 2, /* rightshift */
1157 2, /* size (0 = byte, 1 = short, 2 = long) */
1158 26, /* bitsize */
1159 FALSE, /* pc_relative */
1160 0, /* bitpos */
1161 complain_overflow_dont, /* complain_on_overflow */
1162 /* This needs complex overflow
1163 detection, because the upper four
1164 bits must match the PC. */
1165 mips16_jump_reloc, /* special_function */
1166 "R_MIPS16_26", /* name */
1167 TRUE, /* partial_inplace */
1168 0x3ffffff, /* src_mask */
1169 0x3ffffff, /* dst_mask */
1170 FALSE); /* pcrel_offset */
1172 /* The reloc used for the mips16 gprel instruction. */
1173 static reloc_howto_type elf_mips16_gprel_howto =
1174 HOWTO (R_MIPS16_GPREL, /* type */
1175 0, /* rightshift */
1176 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 16, /* bitsize */
1178 FALSE, /* pc_relative */
1179 0, /* bitpos */
1180 complain_overflow_signed, /* complain_on_overflow */
1181 mips16_gprel_reloc, /* special_function */
1182 "R_MIPS16_GPREL", /* name */
1183 TRUE, /* partial_inplace */
1184 0x07ff001f, /* src_mask */
1185 0x07ff001f, /* dst_mask */
1186 FALSE); /* pcrel_offset */
1188 /* GNU extension to record C++ vtable hierarchy */
1189 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1190 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1191 0, /* rightshift */
1192 2, /* size (0 = byte, 1 = short, 2 = long) */
1193 0, /* bitsize */
1194 FALSE, /* pc_relative */
1195 0, /* bitpos */
1196 complain_overflow_dont, /* complain_on_overflow */
1197 NULL, /* special_function */
1198 "R_MIPS_GNU_VTINHERIT", /* name */
1199 FALSE, /* partial_inplace */
1200 0, /* src_mask */
1201 0, /* dst_mask */
1202 FALSE); /* pcrel_offset */
1204 /* GNU extension to record C++ vtable member usage */
1205 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1206 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1207 0, /* rightshift */
1208 2, /* size (0 = byte, 1 = short, 2 = long) */
1209 0, /* bitsize */
1210 FALSE, /* pc_relative */
1211 0, /* bitpos */
1212 complain_overflow_dont, /* complain_on_overflow */
1213 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1214 "R_MIPS_GNU_VTENTRY", /* name */
1215 FALSE, /* partial_inplace */
1216 0, /* src_mask */
1217 0, /* dst_mask */
1218 FALSE); /* pcrel_offset */
1220 /* Swap in a MIPS 64-bit Rel reloc. */
1222 static void
1223 mips_elf64_swap_reloc_in (abfd, src, dst)
1224 bfd *abfd;
1225 const Elf64_Mips_External_Rel *src;
1226 Elf64_Mips_Internal_Rela *dst;
1228 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1229 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1230 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1231 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1232 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1233 dst->r_type = H_GET_8 (abfd, src->r_type);
1234 dst->r_addend = 0;
1237 /* Swap in a MIPS 64-bit Rela reloc. */
1239 static void
1240 mips_elf64_swap_reloca_in (abfd, src, dst)
1241 bfd *abfd;
1242 const Elf64_Mips_External_Rela *src;
1243 Elf64_Mips_Internal_Rela *dst;
1245 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1246 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1247 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1248 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1249 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1250 dst->r_type = H_GET_8 (abfd, src->r_type);
1251 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1254 /* Swap out a MIPS 64-bit Rel reloc. */
1256 static void
1257 mips_elf64_swap_reloc_out (abfd, src, dst)
1258 bfd *abfd;
1259 const Elf64_Mips_Internal_Rela *src;
1260 Elf64_Mips_External_Rel *dst;
1262 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1263 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1264 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1265 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1266 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1267 H_PUT_8 (abfd, src->r_type, dst->r_type);
1270 /* Swap out a MIPS 64-bit Rela reloc. */
1272 static void
1273 mips_elf64_swap_reloca_out (abfd, src, dst)
1274 bfd *abfd;
1275 const Elf64_Mips_Internal_Rela *src;
1276 Elf64_Mips_External_Rela *dst;
1278 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1279 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1280 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1281 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1282 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1283 H_PUT_8 (abfd, src->r_type, dst->r_type);
1284 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1287 /* Swap in a MIPS 64-bit Rel reloc. */
1289 static void
1290 mips_elf64_be_swap_reloc_in (abfd, src, dst)
1291 bfd *abfd;
1292 const bfd_byte *src;
1293 Elf_Internal_Rela *dst;
1295 Elf64_Mips_Internal_Rela mirel;
1297 mips_elf64_swap_reloc_in (abfd,
1298 (const Elf64_Mips_External_Rel *) src,
1299 &mirel);
1301 dst[0].r_offset = mirel.r_offset;
1302 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1303 dst[0].r_addend = 0;
1304 dst[1].r_offset = mirel.r_offset;
1305 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1306 dst[1].r_addend = 0;
1307 dst[2].r_offset = mirel.r_offset;
1308 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1309 dst[2].r_addend = 0;
1312 /* Swap in a MIPS 64-bit Rela reloc. */
1314 static void
1315 mips_elf64_be_swap_reloca_in (abfd, src, dst)
1316 bfd *abfd;
1317 const bfd_byte *src;
1318 Elf_Internal_Rela *dst;
1320 Elf64_Mips_Internal_Rela mirela;
1322 mips_elf64_swap_reloca_in (abfd,
1323 (const Elf64_Mips_External_Rela *) src,
1324 &mirela);
1326 dst[0].r_offset = mirela.r_offset;
1327 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1328 dst[0].r_addend = mirela.r_addend;
1329 dst[1].r_offset = mirela.r_offset;
1330 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1331 dst[1].r_addend = 0;
1332 dst[2].r_offset = mirela.r_offset;
1333 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1334 dst[2].r_addend = 0;
1337 /* Swap out a MIPS 64-bit Rel reloc. */
1339 static void
1340 mips_elf64_be_swap_reloc_out (abfd, src, dst)
1341 bfd *abfd;
1342 const Elf_Internal_Rela *src;
1343 bfd_byte *dst;
1345 Elf64_Mips_Internal_Rela mirel;
1347 mirel.r_offset = src[0].r_offset;
1348 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1349 #if 0
1350 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1351 #endif
1353 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1354 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1355 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1356 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1357 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1359 mips_elf64_swap_reloc_out (abfd, &mirel,
1360 (Elf64_Mips_External_Rel *) dst);
1363 /* Swap out a MIPS 64-bit Rela reloc. */
1365 static void
1366 mips_elf64_be_swap_reloca_out (abfd, src, dst)
1367 bfd *abfd;
1368 const Elf_Internal_Rela *src;
1369 bfd_byte *dst;
1371 Elf64_Mips_Internal_Rela mirela;
1373 mirela.r_offset = src[0].r_offset;
1374 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1375 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1377 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1378 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1379 mirela.r_addend = src[0].r_addend;
1380 BFD_ASSERT(src[1].r_addend == 0);
1381 BFD_ASSERT(src[2].r_addend == 0);
1383 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1384 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1385 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1387 mips_elf64_swap_reloca_out (abfd, &mirela,
1388 (Elf64_Mips_External_Rela *) dst);
1391 /* Do a R_MIPS_HI16 relocation. */
1393 static bfd_reloc_status_type
1394 mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data, input_section,
1395 output_bfd, error_message)
1396 bfd *abfd ATTRIBUTE_UNUSED;
1397 arelent *reloc_entry;
1398 asymbol *symbol;
1399 PTR data ATTRIBUTE_UNUSED;
1400 asection *input_section;
1401 bfd *output_bfd;
1402 char **error_message ATTRIBUTE_UNUSED;
1404 /* If we're relocating, and this is an external symbol, we don't
1405 want to change anything. */
1406 if (output_bfd != (bfd *) NULL
1407 && (symbol->flags & BSF_SECTION_SYM) == 0
1408 && (! reloc_entry->howto->partial_inplace
1409 || reloc_entry->addend == 0))
1411 reloc_entry->address += input_section->output_offset;
1412 return bfd_reloc_ok;
1415 if (((reloc_entry->addend & 0xffff) + 0x8000) & ~0xffff)
1416 reloc_entry->addend += 0x8000;
1418 return bfd_reloc_continue;
1421 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1422 table used for PIC code. If the symbol is an external symbol, the
1423 instruction is modified to contain the offset of the appropriate
1424 entry in the global offset table. If the symbol is a section
1425 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1426 addends are combined to form the real addend against the section
1427 symbol; the GOT16 is modified to contain the offset of an entry in
1428 the global offset table, and the LO16 is modified to offset it
1429 appropriately. Thus an offset larger than 16 bits requires a
1430 modified value in the global offset table.
1432 This implementation suffices for the assembler, but the linker does
1433 not yet know how to create global offset tables. */
1435 static bfd_reloc_status_type
1436 mips_elf64_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1437 output_bfd, error_message)
1438 bfd *abfd;
1439 arelent *reloc_entry;
1440 asymbol *symbol;
1441 PTR data;
1442 asection *input_section;
1443 bfd *output_bfd;
1444 char **error_message;
1446 /* If we're relocating, and this is a local symbol, we can handle it
1447 just like an R_MIPS_HI16. */
1448 if (output_bfd != (bfd *) NULL
1449 && (symbol->flags & BSF_SECTION_SYM) != 0)
1450 return mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data,
1451 input_section, output_bfd, error_message);
1454 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1455 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1456 input_section, output_bfd, error_message);
1459 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1460 dangerous relocation. */
1462 static bfd_boolean
1463 mips_elf64_assign_gp (output_bfd, pgp)
1464 bfd *output_bfd;
1465 bfd_vma *pgp;
1467 unsigned int count;
1468 asymbol **sym;
1469 unsigned int i;
1471 /* If we've already figured out what GP will be, just return it. */
1472 *pgp = _bfd_get_gp_value (output_bfd);
1473 if (*pgp)
1474 return TRUE;
1476 count = bfd_get_symcount (output_bfd);
1477 sym = bfd_get_outsymbols (output_bfd);
1479 /* The linker script will have created a symbol named `_gp' with the
1480 appropriate value. */
1481 if (sym == (asymbol **) NULL)
1482 i = count;
1483 else
1485 for (i = 0; i < count; i++, sym++)
1487 register const char *name;
1489 name = bfd_asymbol_name (*sym);
1490 if (*name == '_' && strcmp (name, "_gp") == 0)
1492 *pgp = bfd_asymbol_value (*sym);
1493 _bfd_set_gp_value (output_bfd, *pgp);
1494 break;
1499 if (i >= count)
1501 /* Only get the error once. */
1502 *pgp = 4;
1503 _bfd_set_gp_value (output_bfd, *pgp);
1504 return FALSE;
1507 return TRUE;
1510 /* We have to figure out the gp value, so that we can adjust the
1511 symbol value correctly. We look up the symbol _gp in the output
1512 BFD. If we can't find it, we're stuck. We cache it in the ELF
1513 target data. We don't need to adjust the symbol value for an
1514 external symbol if we are producing relocateable output. */
1516 static bfd_reloc_status_type
1517 mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, pgp)
1518 bfd *output_bfd;
1519 asymbol *symbol;
1520 bfd_boolean relocateable;
1521 char **error_message;
1522 bfd_vma *pgp;
1524 if (bfd_is_und_section (symbol->section)
1525 && ! relocateable)
1527 *pgp = 0;
1528 return bfd_reloc_undefined;
1531 *pgp = _bfd_get_gp_value (output_bfd);
1532 if (*pgp == 0
1533 && (! relocateable
1534 || (symbol->flags & BSF_SECTION_SYM) != 0))
1536 if (relocateable)
1538 /* Make up a value. */
1539 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1540 _bfd_set_gp_value (output_bfd, *pgp);
1542 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1544 *error_message =
1545 (char *) _("GP relative relocation when _gp not defined");
1546 return bfd_reloc_dangerous;
1550 return bfd_reloc_ok;
1553 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1554 become the offset from the gp register. */
1556 static bfd_reloc_status_type
1557 mips_elf64_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
1558 output_bfd, error_message)
1559 bfd *abfd;
1560 arelent *reloc_entry;
1561 asymbol *symbol;
1562 PTR data;
1563 asection *input_section;
1564 bfd *output_bfd;
1565 char **error_message;
1567 bfd_boolean relocateable;
1568 bfd_reloc_status_type ret;
1569 bfd_vma gp;
1571 /* If we're relocating, and this is an external symbol with no
1572 addend, we don't want to change anything. We will only have an
1573 addend if this is a newly created reloc, not read from an ELF
1574 file. */
1575 if (output_bfd != (bfd *) NULL
1576 && (symbol->flags & BSF_SECTION_SYM) == 0
1577 && (! reloc_entry->howto->partial_inplace
1578 || reloc_entry->addend == 0))
1580 reloc_entry->address += input_section->output_offset;
1581 return bfd_reloc_ok;
1584 if (output_bfd != (bfd *) NULL)
1585 relocateable = TRUE;
1586 else
1588 relocateable = FALSE;
1589 output_bfd = symbol->section->output_section->owner;
1592 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1593 &gp);
1594 if (ret != bfd_reloc_ok)
1595 return ret;
1597 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1598 input_section, relocateable,
1599 data, gp);
1602 /* Do a R_MIPS_LITERAL relocation. */
1604 static bfd_reloc_status_type
1605 mips_elf64_literal_reloc (abfd, reloc_entry, symbol, data, input_section,
1606 output_bfd, error_message)
1607 bfd *abfd;
1608 arelent *reloc_entry;
1609 asymbol *symbol;
1610 PTR data;
1611 asection *input_section;
1612 bfd *output_bfd;
1613 char **error_message;
1615 bfd_boolean relocateable;
1616 bfd_reloc_status_type ret;
1617 bfd_vma gp;
1619 /* If we're relocating, and this is an external symbol, we don't
1620 want to change anything. */
1621 if (output_bfd != (bfd *) NULL
1622 && (symbol->flags & BSF_SECTION_SYM) == 0
1623 && (! reloc_entry->howto->partial_inplace
1624 || reloc_entry->addend == 0))
1626 reloc_entry->address += input_section->output_offset;
1627 return bfd_reloc_ok;
1630 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1631 if (output_bfd != (bfd *) NULL)
1632 relocateable = TRUE;
1633 else
1635 relocateable = FALSE;
1636 output_bfd = symbol->section->output_section->owner;
1639 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1640 &gp);
1641 if (ret != bfd_reloc_ok)
1642 return ret;
1644 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1645 input_section, relocateable,
1646 data, gp);
1649 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1650 become the offset from the gp register. */
1652 static bfd_reloc_status_type
1653 mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section,
1654 output_bfd, error_message)
1655 bfd *abfd;
1656 arelent *reloc_entry;
1657 asymbol *symbol;
1658 PTR data;
1659 asection *input_section;
1660 bfd *output_bfd;
1661 char **error_message;
1663 bfd_boolean relocateable;
1664 bfd_reloc_status_type ret;
1665 bfd_vma gp;
1666 bfd_vma relocation;
1667 unsigned long val;
1669 /* If we're relocating, and this is an external symbol with no
1670 addend, we don't want to change anything. We will only have an
1671 addend if this is a newly created reloc, not read from an ELF
1672 file. */
1673 if (output_bfd != (bfd *) NULL
1674 && (symbol->flags & BSF_SECTION_SYM) == 0
1675 && reloc_entry->addend == 0)
1677 *error_message = (char *)
1678 _("32bits gp relative relocation occurs for an external symbol");
1679 return bfd_reloc_outofrange;
1682 if (output_bfd != (bfd *) NULL)
1684 relocateable = TRUE;
1685 gp = _bfd_get_gp_value (output_bfd);
1687 else
1689 relocateable = FALSE;
1690 output_bfd = symbol->section->output_section->owner;
1692 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable,
1693 error_message, &gp);
1694 if (ret != bfd_reloc_ok)
1695 return ret;
1698 if (bfd_is_com_section (symbol->section))
1699 relocation = 0;
1700 else
1701 relocation = symbol->value;
1703 relocation += symbol->section->output_section->vma;
1704 relocation += symbol->section->output_offset;
1706 if (reloc_entry->address > input_section->_cooked_size)
1707 return bfd_reloc_outofrange;
1709 if (reloc_entry->howto->src_mask == 0)
1711 /* This case arises with the 64-bit MIPS ELF ABI. */
1712 val = 0;
1714 else
1715 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1717 /* Set val to the offset into the section or symbol. */
1718 val += reloc_entry->addend;
1720 /* Adjust val for the final section location and GP value. If we
1721 are producing relocateable output, we don't want to do this for
1722 an external symbol. */
1723 if (! relocateable
1724 || (symbol->flags & BSF_SECTION_SYM) != 0)
1725 val += relocation - gp;
1727 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1729 if (relocateable)
1730 reloc_entry->address += input_section->output_offset;
1732 return bfd_reloc_ok;
1735 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1736 the rest is at bits 6-10. The bitpos already got right by the howto. */
1738 static bfd_reloc_status_type
1739 mips_elf64_shift6_reloc (abfd, reloc_entry, symbol, data, input_section,
1740 output_bfd, error_message)
1741 bfd *abfd ATTRIBUTE_UNUSED;
1742 arelent *reloc_entry;
1743 asymbol *symbol;
1744 PTR data ATTRIBUTE_UNUSED;
1745 asection *input_section;
1746 bfd *output_bfd;
1747 char **error_message ATTRIBUTE_UNUSED;
1749 /* If we're relocating, and this is an external symbol, we don't
1750 want to change anything. */
1751 if (output_bfd != (bfd *) NULL
1752 && (symbol->flags & BSF_SECTION_SYM) == 0
1753 && (! reloc_entry->howto->partial_inplace
1754 || reloc_entry->addend == 0))
1756 reloc_entry->address += input_section->output_offset;
1757 return bfd_reloc_ok;
1760 reloc_entry->addend = (reloc_entry->addend & 0x00007c0)
1761 | (reloc_entry->addend & 0x00000800) >> 9;
1763 return bfd_reloc_continue;
1766 /* Handle a mips16 jump. */
1768 static bfd_reloc_status_type
1769 mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
1770 output_bfd, error_message)
1771 bfd *abfd ATTRIBUTE_UNUSED;
1772 arelent *reloc_entry;
1773 asymbol *symbol;
1774 PTR data ATTRIBUTE_UNUSED;
1775 asection *input_section;
1776 bfd *output_bfd;
1777 char **error_message ATTRIBUTE_UNUSED;
1779 if (output_bfd != (bfd *) NULL
1780 && (symbol->flags & BSF_SECTION_SYM) == 0
1781 && (! reloc_entry->howto->partial_inplace
1782 || reloc_entry->addend == 0))
1784 reloc_entry->address += input_section->output_offset;
1785 return bfd_reloc_ok;
1788 /* FIXME. */
1790 static bfd_boolean warned;
1792 if (! warned)
1793 (*_bfd_error_handler)
1794 (_("Linking mips16 objects into %s format is not supported"),
1795 bfd_get_target (input_section->output_section->owner));
1796 warned = TRUE;
1799 return bfd_reloc_undefined;
1802 /* Handle a mips16 GP relative reloc. */
1804 static bfd_reloc_status_type
1805 mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
1806 output_bfd, error_message)
1807 bfd *abfd;
1808 arelent *reloc_entry;
1809 asymbol *symbol;
1810 PTR data;
1811 asection *input_section;
1812 bfd *output_bfd;
1813 char **error_message;
1815 bfd_boolean relocateable;
1816 bfd_reloc_status_type ret;
1817 bfd_vma gp;
1818 unsigned short extend, insn;
1819 unsigned long final;
1821 /* If we're relocating, and this is an external symbol with no
1822 addend, we don't want to change anything. We will only have an
1823 addend if this is a newly created reloc, not read from an ELF
1824 file. */
1825 if (output_bfd != NULL
1826 && (symbol->flags & BSF_SECTION_SYM) == 0
1827 && reloc_entry->addend == 0)
1829 reloc_entry->address += input_section->output_offset;
1830 return bfd_reloc_ok;
1833 if (output_bfd != NULL)
1834 relocateable = TRUE;
1835 else
1837 relocateable = FALSE;
1838 output_bfd = symbol->section->output_section->owner;
1841 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1842 &gp);
1843 if (ret != bfd_reloc_ok)
1844 return ret;
1846 if (reloc_entry->address > input_section->_cooked_size)
1847 return bfd_reloc_outofrange;
1849 /* Pick up the mips16 extend instruction and the real instruction. */
1850 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1851 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1853 /* Stuff the current addend back as a 32 bit value, do the usual
1854 relocation, and then clean up. */
1855 bfd_put_32 (abfd,
1856 (bfd_vma) (((extend & 0x1f) << 11)
1857 | (extend & 0x7e0)
1858 | (insn & 0x1f)),
1859 (bfd_byte *) data + reloc_entry->address);
1861 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1862 input_section, relocateable, data, gp);
1864 final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1865 bfd_put_16 (abfd,
1866 (bfd_vma) ((extend & 0xf800)
1867 | ((final >> 11) & 0x1f)
1868 | (final & 0x7e0)),
1869 (bfd_byte *) data + reloc_entry->address);
1870 bfd_put_16 (abfd,
1871 (bfd_vma) ((insn & 0xffe0)
1872 | (final & 0x1f)),
1873 (bfd_byte *) data + reloc_entry->address + 2);
1875 return ret;
1878 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1880 struct elf_reloc_map {
1881 bfd_reloc_code_real_type bfd_val;
1882 enum elf_mips_reloc_type elf_val;
1885 static const struct elf_reloc_map mips_reloc_map[] =
1887 { BFD_RELOC_NONE, R_MIPS_NONE },
1888 { BFD_RELOC_16, R_MIPS_16 },
1889 { BFD_RELOC_32, R_MIPS_32 },
1890 /* There is no BFD reloc for R_MIPS_REL32. */
1891 { BFD_RELOC_64, R_MIPS_64 },
1892 { BFD_RELOC_CTOR, R_MIPS_64 },
1893 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1894 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1895 { BFD_RELOC_LO16, R_MIPS_LO16 },
1896 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1897 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1898 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1899 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1900 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1901 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1902 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1903 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1904 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1905 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1906 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1907 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1908 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1909 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1910 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1911 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1912 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1913 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1914 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1915 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1916 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1917 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1918 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1919 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1920 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1921 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1924 /* Given a BFD reloc type, return a howto structure. */
1926 static reloc_howto_type *
1927 bfd_elf64_bfd_reloc_type_lookup (abfd, code)
1928 bfd *abfd ATTRIBUTE_UNUSED;
1929 bfd_reloc_code_real_type code;
1931 unsigned int i;
1932 /* FIXME: We default to RELA here instead of choosing the right
1933 relocation variant. */
1934 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
1936 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1937 i++)
1939 if (mips_reloc_map[i].bfd_val == code)
1940 return &howto_table[(int) mips_reloc_map[i].elf_val];
1943 switch (code)
1945 case BFD_RELOC_MIPS16_JMP:
1946 return &elf_mips16_jump_howto;
1947 case BFD_RELOC_MIPS16_GPREL:
1948 return &elf_mips16_gprel_howto;
1949 case BFD_RELOC_VTABLE_INHERIT:
1950 return &elf_mips_gnu_vtinherit_howto;
1951 case BFD_RELOC_VTABLE_ENTRY:
1952 return &elf_mips_gnu_vtentry_howto;
1953 default:
1954 bfd_set_error (bfd_error_bad_value);
1955 return NULL;
1959 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1961 static reloc_howto_type *
1962 mips_elf64_rtype_to_howto (r_type, rela_p)
1963 unsigned int r_type;
1964 bfd_boolean rela_p;
1966 switch (r_type)
1968 case R_MIPS16_26:
1969 return &elf_mips16_jump_howto;
1970 case R_MIPS16_GPREL:
1971 return &elf_mips16_gprel_howto;
1972 case R_MIPS_GNU_VTINHERIT:
1973 return &elf_mips_gnu_vtinherit_howto;
1974 case R_MIPS_GNU_VTENTRY:
1975 return &elf_mips_gnu_vtentry_howto;
1976 default:
1977 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1978 if (rela_p)
1979 return &mips_elf64_howto_table_rela[r_type];
1980 else
1981 return &mips_elf64_howto_table_rel[r_type];
1982 break;
1986 /* Prevent relocation handling by bfd for MIPS ELF64. */
1988 static void
1989 mips_elf64_info_to_howto_rel (abfd, cache_ptr, dst)
1990 bfd *abfd ATTRIBUTE_UNUSED;
1991 arelent *cache_ptr ATTRIBUTE_UNUSED;
1992 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
1994 BFD_ASSERT (0);
1997 static void
1998 mips_elf64_info_to_howto_rela (abfd, cache_ptr, dst)
1999 bfd *abfd ATTRIBUTE_UNUSED;
2000 arelent *cache_ptr ATTRIBUTE_UNUSED;
2001 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
2003 BFD_ASSERT (0);
2006 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2007 to three relocs, we must tell the user to allocate more space. */
2009 static long
2010 mips_elf64_get_reloc_upper_bound (abfd, sec)
2011 bfd *abfd ATTRIBUTE_UNUSED;
2012 asection *sec;
2014 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2017 /* Read the relocations from one reloc section. */
2019 static bfd_boolean
2020 mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
2021 bfd *abfd;
2022 asection *asect;
2023 asymbol **symbols;
2024 const Elf_Internal_Shdr *rel_hdr;
2026 PTR allocated = NULL;
2027 bfd_byte *native_relocs;
2028 arelent *relents;
2029 arelent *relent;
2030 bfd_vma count;
2031 bfd_vma i;
2032 int entsize;
2033 reloc_howto_type *howto_table;
2035 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
2036 if (allocated == NULL)
2037 return FALSE;
2039 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2040 || (bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
2041 goto error_return;
2043 native_relocs = (bfd_byte *) allocated;
2045 relents = asect->relocation + asect->reloc_count;
2047 entsize = rel_hdr->sh_entsize;
2048 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2049 || entsize == sizeof (Elf64_Mips_External_Rela));
2051 count = rel_hdr->sh_size / entsize;
2053 if (entsize == sizeof (Elf64_Mips_External_Rel))
2054 howto_table = mips_elf64_howto_table_rel;
2055 else
2056 howto_table = mips_elf64_howto_table_rela;
2058 relent = relents;
2059 for (i = 0; i < count; i++, native_relocs += entsize)
2061 Elf64_Mips_Internal_Rela rela;
2062 bfd_boolean used_sym, used_ssym;
2063 int ir;
2065 if (entsize == sizeof (Elf64_Mips_External_Rela))
2066 mips_elf64_swap_reloca_in (abfd,
2067 (Elf64_Mips_External_Rela *) native_relocs,
2068 &rela);
2069 else
2070 mips_elf64_swap_reloc_in (abfd,
2071 (Elf64_Mips_External_Rel *) native_relocs,
2072 &rela);
2074 /* Each entry represents exactly three actual relocations. */
2076 used_sym = FALSE;
2077 used_ssym = FALSE;
2078 for (ir = 0; ir < 3; ir++)
2080 enum elf_mips_reloc_type type;
2082 switch (ir)
2084 default:
2085 abort ();
2086 case 0:
2087 type = (enum elf_mips_reloc_type) rela.r_type;
2088 break;
2089 case 1:
2090 type = (enum elf_mips_reloc_type) rela.r_type2;
2091 break;
2092 case 2:
2093 type = (enum elf_mips_reloc_type) rela.r_type3;
2094 break;
2097 /* Some types require symbols, whereas some do not. */
2098 switch (type)
2100 case R_MIPS_NONE:
2101 case R_MIPS_LITERAL:
2102 case R_MIPS_INSERT_A:
2103 case R_MIPS_INSERT_B:
2104 case R_MIPS_DELETE:
2105 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2106 break;
2108 default:
2109 if (! used_sym)
2111 if (rela.r_sym == 0)
2112 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2113 else
2115 asymbol **ps, *s;
2117 ps = symbols + rela.r_sym - 1;
2118 s = *ps;
2119 if ((s->flags & BSF_SECTION_SYM) == 0)
2120 relent->sym_ptr_ptr = ps;
2121 else
2122 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2125 used_sym = TRUE;
2127 else if (! used_ssym)
2129 switch (rela.r_ssym)
2131 case RSS_UNDEF:
2132 relent->sym_ptr_ptr =
2133 bfd_abs_section_ptr->symbol_ptr_ptr;
2134 break;
2136 case RSS_GP:
2137 case RSS_GP0:
2138 case RSS_LOC:
2139 /* FIXME: I think these need to be handled using
2140 special howto structures. */
2141 BFD_ASSERT (0);
2142 break;
2144 default:
2145 BFD_ASSERT (0);
2146 break;
2149 used_ssym = TRUE;
2151 else
2152 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2154 break;
2157 /* The address of an ELF reloc is section relative for an
2158 object file, and absolute for an executable file or
2159 shared library. The address of a BFD reloc is always
2160 section relative. */
2161 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2162 relent->address = rela.r_offset;
2163 else
2164 relent->address = rela.r_offset - asect->vma;
2166 relent->addend = rela.r_addend;
2168 relent->howto = &howto_table[(int) type];
2170 ++relent;
2174 asect->reloc_count += (relent - relents) / 3;
2176 if (allocated != NULL)
2177 free (allocated);
2179 return TRUE;
2181 error_return:
2182 if (allocated != NULL)
2183 free (allocated);
2184 return FALSE;
2187 /* Read the relocations. On Irix 6, there can be two reloc sections
2188 associated with a single data section. */
2190 static bfd_boolean
2191 mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
2192 bfd *abfd;
2193 asection *asect;
2194 asymbol **symbols;
2195 bfd_boolean dynamic;
2197 bfd_size_type amt;
2198 struct bfd_elf_section_data * const d = elf_section_data (asect);
2200 if (dynamic)
2202 bfd_set_error (bfd_error_invalid_operation);
2203 return FALSE;
2206 if (asect->relocation != NULL
2207 || (asect->flags & SEC_RELOC) == 0
2208 || asect->reloc_count == 0)
2209 return TRUE;
2211 /* Allocate space for 3 arelent structures for each Rel structure. */
2212 amt = asect->reloc_count;
2213 amt *= 3 * sizeof (arelent);
2214 asect->relocation = (arelent *) bfd_alloc (abfd, amt);
2215 if (asect->relocation == NULL)
2216 return FALSE;
2218 /* The slurp_one_reloc_table routine increments reloc_count. */
2219 asect->reloc_count = 0;
2221 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
2222 return FALSE;
2223 if (d->rel_hdr2 != NULL)
2225 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
2226 d->rel_hdr2))
2227 return FALSE;
2230 return TRUE;
2233 /* Write out the relocations. */
2235 static void
2236 mips_elf64_write_relocs (abfd, sec, data)
2237 bfd *abfd;
2238 asection *sec;
2239 PTR data;
2241 bfd_boolean *failedp = (bfd_boolean *) data;
2242 int count;
2243 Elf_Internal_Shdr *rel_hdr;
2244 unsigned int idx;
2246 /* If we have already failed, don't do anything. */
2247 if (*failedp)
2248 return;
2250 if ((sec->flags & SEC_RELOC) == 0)
2251 return;
2253 /* The linker backend writes the relocs out itself, and sets the
2254 reloc_count field to zero to inhibit writing them here. Also,
2255 sometimes the SEC_RELOC flag gets set even when there aren't any
2256 relocs. */
2257 if (sec->reloc_count == 0)
2258 return;
2260 /* We can combine up to three relocs that refer to the same address
2261 if the latter relocs have no associated symbol. */
2262 count = 0;
2263 for (idx = 0; idx < sec->reloc_count; idx++)
2265 bfd_vma addr;
2266 unsigned int i;
2268 ++count;
2270 addr = sec->orelocation[idx]->address;
2271 for (i = 0; i < 2; i++)
2273 arelent *r;
2275 if (idx + 1 >= sec->reloc_count)
2276 break;
2277 r = sec->orelocation[idx + 1];
2278 if (r->address != addr
2279 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2280 || (*r->sym_ptr_ptr)->value != 0)
2281 break;
2283 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2285 ++idx;
2289 rel_hdr = &elf_section_data (sec)->rel_hdr;
2291 /* Do the actual relocation. */
2293 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2294 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2295 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2296 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2297 else
2298 BFD_ASSERT (0);
2301 static void
2302 mips_elf64_write_rel (abfd, sec, rel_hdr, count, data)
2303 bfd *abfd;
2304 asection *sec;
2305 Elf_Internal_Shdr *rel_hdr;
2306 int *count;
2307 PTR data;
2309 bfd_boolean *failedp = (bfd_boolean *) data;
2310 Elf64_Mips_External_Rel *ext_rel;
2311 unsigned int idx;
2312 asymbol *last_sym = 0;
2313 int last_sym_idx = 0;
2315 rel_hdr->sh_size = (bfd_vma)(rel_hdr->sh_entsize * *count);
2316 rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
2317 if (rel_hdr->contents == NULL)
2319 *failedp = TRUE;
2320 return;
2323 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2324 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2326 arelent *ptr;
2327 Elf64_Mips_Internal_Rela int_rel;
2328 asymbol *sym;
2329 int n;
2330 unsigned int i;
2332 ptr = sec->orelocation[idx];
2334 /* The address of an ELF reloc is section relative for an object
2335 file, and absolute for an executable file or shared library.
2336 The address of a BFD reloc is always section relative. */
2337 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2338 int_rel.r_offset = ptr->address;
2339 else
2340 int_rel.r_offset = ptr->address + sec->vma;
2342 sym = *ptr->sym_ptr_ptr;
2343 if (sym == last_sym)
2344 n = last_sym_idx;
2345 else
2347 last_sym = sym;
2348 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2349 if (n < 0)
2351 *failedp = TRUE;
2352 return;
2354 last_sym_idx = n;
2357 int_rel.r_sym = n;
2358 int_rel.r_ssym = RSS_UNDEF;
2360 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2361 && ! _bfd_elf_validate_reloc (abfd, ptr))
2363 *failedp = TRUE;
2364 return;
2367 int_rel.r_type = ptr->howto->type;
2368 int_rel.r_type2 = (int) R_MIPS_NONE;
2369 int_rel.r_type3 = (int) R_MIPS_NONE;
2371 for (i = 0; i < 2; i++)
2373 arelent *r;
2375 if (idx + 1 >= sec->reloc_count)
2376 break;
2377 r = sec->orelocation[idx + 1];
2378 if (r->address != ptr->address
2379 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2380 || (*r->sym_ptr_ptr)->value != 0)
2381 break;
2383 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2385 if (i == 0)
2386 int_rel.r_type2 = r->howto->type;
2387 else
2388 int_rel.r_type3 = r->howto->type;
2390 ++idx;
2393 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2396 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2397 == *count);
2400 static void
2401 mips_elf64_write_rela (abfd, sec, rela_hdr, count, data)
2402 bfd *abfd;
2403 asection *sec;
2404 Elf_Internal_Shdr *rela_hdr;
2405 int *count;
2406 PTR data;
2408 bfd_boolean *failedp = (bfd_boolean *) data;
2409 Elf64_Mips_External_Rela *ext_rela;
2410 unsigned int idx;
2411 asymbol *last_sym = 0;
2412 int last_sym_idx = 0;
2414 rela_hdr->sh_size = (bfd_vma)(rela_hdr->sh_entsize * *count);
2415 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
2416 if (rela_hdr->contents == NULL)
2418 *failedp = TRUE;
2419 return;
2422 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2423 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2425 arelent *ptr;
2426 Elf64_Mips_Internal_Rela int_rela;
2427 asymbol *sym;
2428 int n;
2429 unsigned int i;
2431 ptr = sec->orelocation[idx];
2433 /* The address of an ELF reloc is section relative for an object
2434 file, and absolute for an executable file or shared library.
2435 The address of a BFD reloc is always section relative. */
2436 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2437 int_rela.r_offset = ptr->address;
2438 else
2439 int_rela.r_offset = ptr->address + sec->vma;
2441 sym = *ptr->sym_ptr_ptr;
2442 if (sym == last_sym)
2443 n = last_sym_idx;
2444 else
2446 last_sym = sym;
2447 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2448 if (n < 0)
2450 *failedp = TRUE;
2451 return;
2453 last_sym_idx = n;
2456 int_rela.r_sym = n;
2457 int_rela.r_addend = ptr->addend;
2458 int_rela.r_ssym = RSS_UNDEF;
2460 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2461 && ! _bfd_elf_validate_reloc (abfd, ptr))
2463 *failedp = TRUE;
2464 return;
2467 int_rela.r_type = ptr->howto->type;
2468 int_rela.r_type2 = (int) R_MIPS_NONE;
2469 int_rela.r_type3 = (int) R_MIPS_NONE;
2471 for (i = 0; i < 2; i++)
2473 arelent *r;
2475 if (idx + 1 >= sec->reloc_count)
2476 break;
2477 r = sec->orelocation[idx + 1];
2478 if (r->address != ptr->address
2479 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2480 || (*r->sym_ptr_ptr)->value != 0)
2481 break;
2483 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2485 if (i == 0)
2486 int_rela.r_type2 = r->howto->type;
2487 else
2488 int_rela.r_type3 = r->howto->type;
2490 ++idx;
2493 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2496 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2497 == *count);
2500 /* Set the right machine number for a MIPS ELF file. */
2502 static bfd_boolean
2503 mips_elf64_object_p (abfd)
2504 bfd *abfd;
2506 unsigned long mach;
2508 /* Irix 6 is broken. Object file symbol tables are not always
2509 sorted correctly such that local symbols precede global symbols,
2510 and the sh_info field in the symbol table is not always right. */
2511 if (elf64_mips_irix_compat (abfd) != ict_none)
2512 elf_bad_symtab (abfd) = TRUE;
2514 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2515 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2516 return TRUE;
2519 /* Depending on the target vector we generate some version of Irix
2520 executables or "normal" MIPS ELF ABI executables. */
2521 static irix_compat_t
2522 elf64_mips_irix_compat (abfd)
2523 bfd *abfd;
2525 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2526 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2527 return ict_irix6;
2528 else
2529 return ict_none;
2532 /* ECOFF swapping routines. These are used when dealing with the
2533 .mdebug section, which is in the ECOFF debugging format. */
2534 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2536 /* Symbol table magic number. */
2537 magicSym2,
2538 /* Alignment of debugging information. E.g., 4. */
2540 /* Sizes of external symbolic information. */
2541 sizeof (struct hdr_ext),
2542 sizeof (struct dnr_ext),
2543 sizeof (struct pdr_ext),
2544 sizeof (struct sym_ext),
2545 sizeof (struct opt_ext),
2546 sizeof (struct fdr_ext),
2547 sizeof (struct rfd_ext),
2548 sizeof (struct ext_ext),
2549 /* Functions to swap in external symbolic data. */
2550 ecoff_swap_hdr_in,
2551 ecoff_swap_dnr_in,
2552 ecoff_swap_pdr_in,
2553 ecoff_swap_sym_in,
2554 ecoff_swap_opt_in,
2555 ecoff_swap_fdr_in,
2556 ecoff_swap_rfd_in,
2557 ecoff_swap_ext_in,
2558 _bfd_ecoff_swap_tir_in,
2559 _bfd_ecoff_swap_rndx_in,
2560 /* Functions to swap out external symbolic data. */
2561 ecoff_swap_hdr_out,
2562 ecoff_swap_dnr_out,
2563 ecoff_swap_pdr_out,
2564 ecoff_swap_sym_out,
2565 ecoff_swap_opt_out,
2566 ecoff_swap_fdr_out,
2567 ecoff_swap_rfd_out,
2568 ecoff_swap_ext_out,
2569 _bfd_ecoff_swap_tir_out,
2570 _bfd_ecoff_swap_rndx_out,
2571 /* Function to read in symbolic data. */
2572 _bfd_mips_elf_read_ecoff_info
2575 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2576 standard ELF. This structure is used to redirect the relocation
2577 handling routines. */
2579 const struct elf_size_info mips_elf64_size_info =
2581 sizeof (Elf64_External_Ehdr),
2582 sizeof (Elf64_External_Phdr),
2583 sizeof (Elf64_External_Shdr),
2584 sizeof (Elf64_Mips_External_Rel),
2585 sizeof (Elf64_Mips_External_Rela),
2586 sizeof (Elf64_External_Sym),
2587 sizeof (Elf64_External_Dyn),
2588 sizeof (Elf_External_Note),
2589 4, /* hash-table entry size */
2590 3, /* internal relocations per external relocations */
2591 64, /* arch_size */
2592 8, /* file_align */
2593 ELFCLASS64,
2594 EV_CURRENT,
2595 bfd_elf64_write_out_phdrs,
2596 bfd_elf64_write_shdrs_and_ehdr,
2597 mips_elf64_write_relocs,
2598 bfd_elf64_swap_symbol_in,
2599 bfd_elf64_swap_symbol_out,
2600 mips_elf64_slurp_reloc_table,
2601 bfd_elf64_slurp_symbol_table,
2602 bfd_elf64_swap_dyn_in,
2603 bfd_elf64_swap_dyn_out,
2604 mips_elf64_be_swap_reloc_in,
2605 mips_elf64_be_swap_reloc_out,
2606 mips_elf64_be_swap_reloca_in,
2607 mips_elf64_be_swap_reloca_out
2610 #define ELF_ARCH bfd_arch_mips
2611 #define ELF_MACHINE_CODE EM_MIPS
2613 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2614 a value of 0x1000, and we are compatible.
2615 FIXME: How does this affect NewABI? */
2616 #define ELF_MAXPAGESIZE 0x1000
2618 #define elf_backend_collect TRUE
2619 #define elf_backend_type_change_ok TRUE
2620 #define elf_backend_can_gc_sections TRUE
2621 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2622 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2623 #define elf_backend_object_p mips_elf64_object_p
2624 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2625 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2626 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2627 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2628 #define elf_backend_section_from_bfd_section \
2629 _bfd_mips_elf_section_from_bfd_section
2630 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2631 #define elf_backend_link_output_symbol_hook \
2632 _bfd_mips_elf_link_output_symbol_hook
2633 #define elf_backend_create_dynamic_sections \
2634 _bfd_mips_elf_create_dynamic_sections
2635 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2636 #define elf_backend_adjust_dynamic_symbol \
2637 _bfd_mips_elf_adjust_dynamic_symbol
2638 #define elf_backend_always_size_sections \
2639 _bfd_mips_elf_always_size_sections
2640 #define elf_backend_size_dynamic_sections \
2641 _bfd_mips_elf_size_dynamic_sections
2642 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2643 #define elf_backend_finish_dynamic_symbol \
2644 _bfd_mips_elf_finish_dynamic_symbol
2645 #define elf_backend_finish_dynamic_sections \
2646 _bfd_mips_elf_finish_dynamic_sections
2647 #define elf_backend_final_write_processing \
2648 _bfd_mips_elf_final_write_processing
2649 #define elf_backend_additional_program_headers \
2650 _bfd_mips_elf_additional_program_headers
2651 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2652 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2653 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2654 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2655 #define elf_backend_ignore_discarded_relocs \
2656 _bfd_mips_elf_ignore_discarded_relocs
2657 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2658 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2659 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2660 #define elf_backend_size_info mips_elf64_size_info
2662 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2663 #define elf_backend_plt_header_size 0
2665 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2666 work better/work only in RELA, so we default to this. */
2667 #define elf_backend_may_use_rel_p 1
2668 #define elf_backend_may_use_rela_p 1
2669 #define elf_backend_default_use_rela_p 1
2671 #define elf_backend_write_section _bfd_mips_elf_write_section
2673 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2674 MIPS-specific function only applies to IRIX5, which had no 64-bit
2675 ABI. */
2676 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2677 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2678 #define bfd_elf64_bfd_get_relocated_section_contents \
2679 _bfd_elf_mips_get_relocated_section_contents
2680 #define bfd_elf64_bfd_link_hash_table_create \
2681 _bfd_mips_elf_link_hash_table_create
2682 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2683 #define bfd_elf64_bfd_merge_private_bfd_data \
2684 _bfd_mips_elf_merge_private_bfd_data
2685 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2686 #define bfd_elf64_bfd_print_private_bfd_data \
2687 _bfd_mips_elf_print_private_bfd_data
2689 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2691 /* MIPS ELF64 archive functions. */
2692 #define bfd_elf64_archive_functions
2693 extern bfd_boolean bfd_elf64_archive_slurp_armap
2694 PARAMS ((bfd *));
2695 extern bfd_boolean bfd_elf64_archive_write_armap
2696 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
2697 #define bfd_elf64_archive_slurp_extended_name_table \
2698 _bfd_archive_coff_slurp_extended_name_table
2699 #define bfd_elf64_archive_construct_extended_name_table \
2700 _bfd_archive_coff_construct_extended_name_table
2701 #define bfd_elf64_archive_truncate_arname \
2702 _bfd_archive_coff_truncate_arname
2703 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2704 #define bfd_elf64_archive_openr_next_archived_file \
2705 _bfd_archive_coff_openr_next_archived_file
2706 #define bfd_elf64_archive_get_elt_at_index \
2707 _bfd_archive_coff_get_elt_at_index
2708 #define bfd_elf64_archive_generic_stat_arch_elt \
2709 _bfd_archive_coff_generic_stat_arch_elt
2710 #define bfd_elf64_archive_update_armap_timestamp \
2711 _bfd_archive_coff_update_armap_timestamp
2713 /* The SGI style (n)64 NewABI. */
2714 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2715 #define TARGET_LITTLE_NAME "elf64-littlemips"
2716 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2717 #define TARGET_BIG_NAME "elf64-bigmips"
2719 #include "elf64-target.h"
2721 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2723 /* The SYSV-style 'traditional' (n)64 NewABI. */
2724 #undef TARGET_LITTLE_SYM
2725 #undef TARGET_LITTLE_NAME
2726 #undef TARGET_BIG_SYM
2727 #undef TARGET_BIG_NAME
2729 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2730 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2731 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2732 #define TARGET_BIG_NAME "elf64-tradbigmips"
2734 /* Include the target file again for this target. */
2735 #include "elf64-target.h"