bfd/
[binutils.git] / bfd / elf64-mips.c
blobc8f3127e3c9e660b3748d97106fac32fc01123d6
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
66 static void mips_elf64_swap_reloca_in
67 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
68 static void mips_elf64_swap_reloc_out
69 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
70 static void mips_elf64_swap_reloca_out
71 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
72 static void mips_elf64_be_swap_reloc_in
73 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
74 static void mips_elf64_be_swap_reloc_out
75 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
76 static void mips_elf64_be_swap_reloca_in
77 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
78 static void mips_elf64_be_swap_reloca_out
79 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
80 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
81 (bfd *, bfd_reloc_code_real_type);
82 static reloc_howto_type *mips_elf64_rtype_to_howto
83 (unsigned int, bfd_boolean);
84 static void mips_elf64_info_to_howto_rel
85 (bfd *, arelent *, Elf_Internal_Rela *);
86 static void mips_elf64_info_to_howto_rela
87 (bfd *, arelent *, Elf_Internal_Rela *);
88 static long mips_elf64_get_reloc_upper_bound
89 (bfd *, asection *);
90 static long mips_elf64_canonicalize_reloc
91 (bfd *, asection *, arelent **, asymbol **);
92 static long mips_elf64_get_dynamic_reloc_upper_bound
93 (bfd *);
94 static long mips_elf64_canonicalize_dynamic_reloc
95 (bfd *, arelent **, asymbol **);
96 static bfd_boolean mips_elf64_slurp_one_reloc_table
97 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
98 asymbol **, bfd_boolean);
99 static bfd_boolean mips_elf64_slurp_reloc_table
100 (bfd *, asection *, asymbol **, bfd_boolean);
101 static void mips_elf64_write_relocs
102 (bfd *, asection *, void *);
103 static void mips_elf64_write_rel
104 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
105 static void mips_elf64_write_rela
106 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
107 static bfd_reloc_status_type mips_elf64_gprel16_reloc
108 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
109 static bfd_reloc_status_type mips_elf64_literal_reloc
110 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
111 static bfd_reloc_status_type mips_elf64_gprel32_reloc
112 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
113 static bfd_reloc_status_type mips_elf64_shift6_reloc
114 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
115 static bfd_reloc_status_type mips16_jump_reloc
116 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
117 static bfd_reloc_status_type mips16_gprel_reloc
118 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
119 static bfd_boolean mips_elf64_assign_gp
120 (bfd *, bfd_vma *);
121 static bfd_reloc_status_type mips_elf64_final_gp
122 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
123 static bfd_boolean mips_elf64_object_p
124 (bfd *);
125 static irix_compat_t elf64_mips_irix_compat
126 (bfd *);
127 static bfd_boolean elf64_mips_grok_prstatus
128 (bfd *, Elf_Internal_Note *);
129 static bfd_boolean elf64_mips_grok_psinfo
130 (bfd *, Elf_Internal_Note *);
132 extern const bfd_target bfd_elf64_bigmips_vec;
133 extern const bfd_target bfd_elf64_littlemips_vec;
135 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
136 from smaller values. Start with zero, widen, *then* decrement. */
137 #define MINUS_ONE (((bfd_vma)0) - 1)
139 /* The number of local .got entries we reserve. */
140 #define MIPS_RESERVED_GOTNO (2)
142 /* The relocation table used for SHT_REL sections. */
144 static reloc_howto_type mips_elf64_howto_table_rel[] =
146 /* No relocation. */
147 HOWTO (R_MIPS_NONE, /* type */
148 0, /* rightshift */
149 0, /* size (0 = byte, 1 = short, 2 = long) */
150 0, /* bitsize */
151 FALSE, /* pc_relative */
152 0, /* bitpos */
153 complain_overflow_dont, /* complain_on_overflow */
154 _bfd_mips_elf_generic_reloc, /* special_function */
155 "R_MIPS_NONE", /* name */
156 FALSE, /* partial_inplace */
157 0, /* src_mask */
158 0, /* dst_mask */
159 FALSE), /* pcrel_offset */
161 /* 16 bit relocation. */
162 HOWTO (R_MIPS_16, /* type */
163 0, /* rightshift */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
165 16, /* bitsize */
166 FALSE, /* pc_relative */
167 0, /* bitpos */
168 complain_overflow_signed, /* complain_on_overflow */
169 _bfd_mips_elf_generic_reloc, /* special_function */
170 "R_MIPS_16", /* name */
171 TRUE, /* partial_inplace */
172 0x0000ffff, /* src_mask */
173 0x0000ffff, /* dst_mask */
174 FALSE), /* pcrel_offset */
176 /* 32 bit relocation. */
177 HOWTO (R_MIPS_32, /* type */
178 0, /* rightshift */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
180 32, /* bitsize */
181 FALSE, /* pc_relative */
182 0, /* bitpos */
183 complain_overflow_dont, /* complain_on_overflow */
184 _bfd_mips_elf_generic_reloc, /* special_function */
185 "R_MIPS_32", /* name */
186 TRUE, /* partial_inplace */
187 0xffffffff, /* src_mask */
188 0xffffffff, /* dst_mask */
189 FALSE), /* pcrel_offset */
191 /* 32 bit symbol relative relocation. */
192 HOWTO (R_MIPS_REL32, /* type */
193 0, /* rightshift */
194 2, /* size (0 = byte, 1 = short, 2 = long) */
195 32, /* bitsize */
196 FALSE, /* pc_relative */
197 0, /* bitpos */
198 complain_overflow_dont, /* complain_on_overflow */
199 _bfd_mips_elf_generic_reloc, /* special_function */
200 "R_MIPS_REL32", /* name */
201 TRUE, /* partial_inplace */
202 0xffffffff, /* src_mask */
203 0xffffffff, /* dst_mask */
204 FALSE), /* pcrel_offset */
206 /* 26 bit jump address. */
207 HOWTO (R_MIPS_26, /* type */
208 2, /* rightshift */
209 2, /* size (0 = byte, 1 = short, 2 = long) */
210 26, /* bitsize */
211 FALSE, /* pc_relative */
212 0, /* bitpos */
213 complain_overflow_dont, /* complain_on_overflow */
214 /* This needs complex overflow
215 detection, because the upper 36
216 bits must match the PC + 4. */
217 _bfd_mips_elf_generic_reloc, /* special_function */
218 "R_MIPS_26", /* name */
219 TRUE, /* partial_inplace */
220 0x03ffffff, /* src_mask */
221 0x03ffffff, /* dst_mask */
222 FALSE), /* pcrel_offset */
224 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
225 However, the native IRIX6 tools use them, so we try our best. */
227 /* High 16 bits of symbol value. */
228 HOWTO (R_MIPS_HI16, /* type */
229 16, /* rightshift */
230 2, /* size (0 = byte, 1 = short, 2 = long) */
231 16, /* bitsize */
232 FALSE, /* pc_relative */
233 0, /* bitpos */
234 complain_overflow_dont, /* complain_on_overflow */
235 _bfd_mips_elf_hi16_reloc, /* special_function */
236 "R_MIPS_HI16", /* name */
237 TRUE, /* partial_inplace */
238 0x0000ffff, /* src_mask */
239 0x0000ffff, /* dst_mask */
240 FALSE), /* pcrel_offset */
242 /* Low 16 bits of symbol value. */
243 HOWTO (R_MIPS_LO16, /* type */
244 0, /* rightshift */
245 2, /* size (0 = byte, 1 = short, 2 = long) */
246 16, /* bitsize */
247 FALSE, /* pc_relative */
248 0, /* bitpos */
249 complain_overflow_dont, /* complain_on_overflow */
250 _bfd_mips_elf_lo16_reloc, /* special_function */
251 "R_MIPS_LO16", /* name */
252 TRUE, /* partial_inplace */
253 0x0000ffff, /* src_mask */
254 0x0000ffff, /* dst_mask */
255 FALSE), /* pcrel_offset */
257 /* GP relative reference. */
258 HOWTO (R_MIPS_GPREL16, /* type */
259 0, /* rightshift */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
261 16, /* bitsize */
262 FALSE, /* pc_relative */
263 0, /* bitpos */
264 complain_overflow_signed, /* complain_on_overflow */
265 mips_elf64_gprel16_reloc, /* special_function */
266 "R_MIPS_GPREL16", /* name */
267 TRUE, /* partial_inplace */
268 0x0000ffff, /* src_mask */
269 0x0000ffff, /* dst_mask */
270 FALSE), /* pcrel_offset */
272 /* Reference to literal section. */
273 HOWTO (R_MIPS_LITERAL, /* type */
274 0, /* rightshift */
275 2, /* size (0 = byte, 1 = short, 2 = long) */
276 16, /* bitsize */
277 FALSE, /* pc_relative */
278 0, /* bitpos */
279 complain_overflow_signed, /* complain_on_overflow */
280 mips_elf64_literal_reloc, /* special_function */
281 "R_MIPS_LITERAL", /* name */
282 TRUE, /* partial_inplace */
283 0x0000ffff, /* src_mask */
284 0x0000ffff, /* dst_mask */
285 FALSE), /* pcrel_offset */
287 /* Reference to global offset table. */
288 HOWTO (R_MIPS_GOT16, /* type */
289 0, /* rightshift */
290 2, /* size (0 = byte, 1 = short, 2 = long) */
291 16, /* bitsize */
292 FALSE, /* pc_relative */
293 0, /* bitpos */
294 complain_overflow_signed, /* complain_on_overflow */
295 _bfd_mips_elf_got16_reloc, /* special_function */
296 "R_MIPS_GOT16", /* name */
297 TRUE, /* partial_inplace */
298 0x0000ffff, /* src_mask */
299 0x0000ffff, /* dst_mask */
300 FALSE), /* pcrel_offset */
302 /* 16 bit PC relative reference. Note that the ABI document has a typo
303 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
304 We do the right thing here. */
305 HOWTO (R_MIPS_PC16, /* type */
306 2, /* rightshift */
307 2, /* size (0 = byte, 1 = short, 2 = long) */
308 16, /* bitsize */
309 TRUE, /* pc_relative */
310 0, /* bitpos */
311 complain_overflow_signed, /* complain_on_overflow */
312 _bfd_mips_elf_generic_reloc, /* special_function */
313 "R_MIPS_PC16", /* name */
314 TRUE, /* partial_inplace */
315 0x0000ffff, /* src_mask */
316 0x0000ffff, /* dst_mask */
317 TRUE), /* pcrel_offset */
319 /* 16 bit call through global offset table. */
320 HOWTO (R_MIPS_CALL16, /* type */
321 0, /* rightshift */
322 2, /* size (0 = byte, 1 = short, 2 = long) */
323 16, /* bitsize */
324 FALSE, /* pc_relative */
325 0, /* bitpos */
326 complain_overflow_signed, /* complain_on_overflow */
327 _bfd_mips_elf_generic_reloc, /* special_function */
328 "R_MIPS_CALL16", /* name */
329 TRUE, /* partial_inplace */
330 0x0000ffff, /* src_mask */
331 0x0000ffff, /* dst_mask */
332 FALSE), /* pcrel_offset */
334 /* 32 bit GP relative reference. */
335 HOWTO (R_MIPS_GPREL32, /* type */
336 0, /* rightshift */
337 2, /* size (0 = byte, 1 = short, 2 = long) */
338 32, /* bitsize */
339 FALSE, /* pc_relative */
340 0, /* bitpos */
341 complain_overflow_dont, /* complain_on_overflow */
342 mips_elf64_gprel32_reloc, /* special_function */
343 "R_MIPS_GPREL32", /* name */
344 TRUE, /* partial_inplace */
345 0xffffffff, /* src_mask */
346 0xffffffff, /* dst_mask */
347 FALSE), /* pcrel_offset */
349 EMPTY_HOWTO (13),
350 EMPTY_HOWTO (14),
351 EMPTY_HOWTO (15),
353 /* A 5 bit shift field. */
354 HOWTO (R_MIPS_SHIFT5, /* type */
355 0, /* rightshift */
356 2, /* size (0 = byte, 1 = short, 2 = long) */
357 5, /* bitsize */
358 FALSE, /* pc_relative */
359 6, /* bitpos */
360 complain_overflow_bitfield, /* complain_on_overflow */
361 _bfd_mips_elf_generic_reloc, /* special_function */
362 "R_MIPS_SHIFT5", /* name */
363 TRUE, /* partial_inplace */
364 0x000007c0, /* src_mask */
365 0x000007c0, /* dst_mask */
366 FALSE), /* pcrel_offset */
368 /* A 6 bit shift field. */
369 HOWTO (R_MIPS_SHIFT6, /* type */
370 0, /* rightshift */
371 2, /* size (0 = byte, 1 = short, 2 = long) */
372 6, /* bitsize */
373 FALSE, /* pc_relative */
374 6, /* bitpos */
375 complain_overflow_bitfield, /* complain_on_overflow */
376 mips_elf64_shift6_reloc, /* special_function */
377 "R_MIPS_SHIFT6", /* name */
378 TRUE, /* partial_inplace */
379 0x000007c4, /* src_mask */
380 0x000007c4, /* dst_mask */
381 FALSE), /* pcrel_offset */
383 /* 64 bit relocation. */
384 HOWTO (R_MIPS_64, /* type */
385 0, /* rightshift */
386 4, /* size (0 = byte, 1 = short, 2 = long) */
387 64, /* bitsize */
388 FALSE, /* pc_relative */
389 0, /* bitpos */
390 complain_overflow_dont, /* complain_on_overflow */
391 _bfd_mips_elf_generic_reloc, /* special_function */
392 "R_MIPS_64", /* name */
393 TRUE, /* partial_inplace */
394 MINUS_ONE, /* src_mask */
395 MINUS_ONE, /* dst_mask */
396 FALSE), /* pcrel_offset */
398 /* Displacement in the global offset table. */
399 HOWTO (R_MIPS_GOT_DISP, /* type */
400 0, /* rightshift */
401 2, /* size (0 = byte, 1 = short, 2 = long) */
402 16, /* bitsize */
403 FALSE, /* pc_relative */
404 0, /* bitpos */
405 complain_overflow_signed, /* complain_on_overflow */
406 _bfd_mips_elf_generic_reloc, /* special_function */
407 "R_MIPS_GOT_DISP", /* name */
408 TRUE, /* partial_inplace */
409 0x0000ffff, /* src_mask */
410 0x0000ffff, /* dst_mask */
411 FALSE), /* pcrel_offset */
413 /* Displacement to page pointer in the global offset table. */
414 HOWTO (R_MIPS_GOT_PAGE, /* type */
415 0, /* rightshift */
416 2, /* size (0 = byte, 1 = short, 2 = long) */
417 16, /* bitsize */
418 FALSE, /* pc_relative */
419 0, /* bitpos */
420 complain_overflow_signed, /* complain_on_overflow */
421 _bfd_mips_elf_generic_reloc, /* special_function */
422 "R_MIPS_GOT_PAGE", /* name */
423 TRUE, /* partial_inplace */
424 0x0000ffff, /* src_mask */
425 0x0000ffff, /* dst_mask */
426 FALSE), /* pcrel_offset */
428 /* Offset from page pointer in the global offset table. */
429 HOWTO (R_MIPS_GOT_OFST, /* type */
430 0, /* rightshift */
431 2, /* size (0 = byte, 1 = short, 2 = long) */
432 16, /* bitsize */
433 FALSE, /* pc_relative */
434 0, /* bitpos */
435 complain_overflow_signed, /* complain_on_overflow */
436 _bfd_mips_elf_generic_reloc, /* special_function */
437 "R_MIPS_GOT_OFST", /* name */
438 TRUE, /* partial_inplace */
439 0x0000ffff, /* src_mask */
440 0x0000ffff, /* dst_mask */
441 FALSE), /* pcrel_offset */
443 /* High 16 bits of displacement in global offset table. */
444 HOWTO (R_MIPS_GOT_HI16, /* type */
445 0, /* rightshift */
446 2, /* size (0 = byte, 1 = short, 2 = long) */
447 16, /* bitsize */
448 FALSE, /* pc_relative */
449 0, /* bitpos */
450 complain_overflow_dont, /* complain_on_overflow */
451 _bfd_mips_elf_generic_reloc, /* special_function */
452 "R_MIPS_GOT_HI16", /* name */
453 TRUE, /* partial_inplace */
454 0x0000ffff, /* src_mask */
455 0x0000ffff, /* dst_mask */
456 FALSE), /* pcrel_offset */
458 /* Low 16 bits of displacement in global offset table. */
459 HOWTO (R_MIPS_GOT_LO16, /* type */
460 0, /* rightshift */
461 2, /* size (0 = byte, 1 = short, 2 = long) */
462 16, /* bitsize */
463 FALSE, /* pc_relative */
464 0, /* bitpos */
465 complain_overflow_dont, /* complain_on_overflow */
466 _bfd_mips_elf_generic_reloc, /* special_function */
467 "R_MIPS_GOT_LO16", /* name */
468 TRUE, /* partial_inplace */
469 0x0000ffff, /* src_mask */
470 0x0000ffff, /* dst_mask */
471 FALSE), /* pcrel_offset */
473 /* 64 bit subtraction. */
474 HOWTO (R_MIPS_SUB, /* type */
475 0, /* rightshift */
476 4, /* size (0 = byte, 1 = short, 2 = long) */
477 64, /* bitsize */
478 FALSE, /* pc_relative */
479 0, /* bitpos */
480 complain_overflow_dont, /* complain_on_overflow */
481 _bfd_mips_elf_generic_reloc, /* special_function */
482 "R_MIPS_SUB", /* name */
483 TRUE, /* partial_inplace */
484 MINUS_ONE, /* src_mask */
485 MINUS_ONE, /* dst_mask */
486 FALSE), /* pcrel_offset */
488 /* Insert the addend as an instruction. */
489 /* FIXME: Not handled correctly. */
490 HOWTO (R_MIPS_INSERT_A, /* type */
491 0, /* rightshift */
492 2, /* size (0 = byte, 1 = short, 2 = long) */
493 32, /* bitsize */
494 FALSE, /* pc_relative */
495 0, /* bitpos */
496 complain_overflow_dont, /* complain_on_overflow */
497 _bfd_mips_elf_generic_reloc, /* special_function */
498 "R_MIPS_INSERT_A", /* name */
499 TRUE, /* partial_inplace */
500 0xffffffff, /* src_mask */
501 0xffffffff, /* dst_mask */
502 FALSE), /* pcrel_offset */
504 /* Insert the addend as an instruction, and change all relocations
505 to refer to the old instruction at the address. */
506 /* FIXME: Not handled correctly. */
507 HOWTO (R_MIPS_INSERT_B, /* type */
508 0, /* rightshift */
509 2, /* size (0 = byte, 1 = short, 2 = long) */
510 32, /* bitsize */
511 FALSE, /* pc_relative */
512 0, /* bitpos */
513 complain_overflow_dont, /* complain_on_overflow */
514 _bfd_mips_elf_generic_reloc, /* special_function */
515 "R_MIPS_INSERT_B", /* name */
516 TRUE, /* partial_inplace */
517 0xffffffff, /* src_mask */
518 0xffffffff, /* dst_mask */
519 FALSE), /* pcrel_offset */
521 /* Delete a 32 bit instruction. */
522 /* FIXME: Not handled correctly. */
523 HOWTO (R_MIPS_DELETE, /* type */
524 0, /* rightshift */
525 2, /* size (0 = byte, 1 = short, 2 = long) */
526 32, /* bitsize */
527 FALSE, /* pc_relative */
528 0, /* bitpos */
529 complain_overflow_dont, /* complain_on_overflow */
530 _bfd_mips_elf_generic_reloc, /* special_function */
531 "R_MIPS_DELETE", /* name */
532 TRUE, /* partial_inplace */
533 0xffffffff, /* src_mask */
534 0xffffffff, /* dst_mask */
535 FALSE), /* pcrel_offset */
537 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
538 We don't, because
539 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
540 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
541 fallable heuristics.
542 b) No other NewABI toolchain actually emits such relocations. */
543 EMPTY_HOWTO (R_MIPS_HIGHER),
544 EMPTY_HOWTO (R_MIPS_HIGHEST),
546 /* High 16 bits of displacement in global offset table. */
547 HOWTO (R_MIPS_CALL_HI16, /* type */
548 0, /* rightshift */
549 2, /* size (0 = byte, 1 = short, 2 = long) */
550 16, /* bitsize */
551 FALSE, /* pc_relative */
552 0, /* bitpos */
553 complain_overflow_dont, /* complain_on_overflow */
554 _bfd_mips_elf_generic_reloc, /* special_function */
555 "R_MIPS_CALL_HI16", /* name */
556 TRUE, /* partial_inplace */
557 0x0000ffff, /* src_mask */
558 0x0000ffff, /* dst_mask */
559 FALSE), /* pcrel_offset */
561 /* Low 16 bits of displacement in global offset table. */
562 HOWTO (R_MIPS_CALL_LO16, /* type */
563 0, /* rightshift */
564 2, /* size (0 = byte, 1 = short, 2 = long) */
565 16, /* bitsize */
566 FALSE, /* pc_relative */
567 0, /* bitpos */
568 complain_overflow_dont, /* complain_on_overflow */
569 _bfd_mips_elf_generic_reloc, /* special_function */
570 "R_MIPS_CALL_LO16", /* name */
571 TRUE, /* partial_inplace */
572 0x0000ffff, /* src_mask */
573 0x0000ffff, /* dst_mask */
574 FALSE), /* pcrel_offset */
576 /* Section displacement, used by an associated event location section. */
577 HOWTO (R_MIPS_SCN_DISP, /* type */
578 0, /* rightshift */
579 2, /* size (0 = byte, 1 = short, 2 = long) */
580 32, /* bitsize */
581 FALSE, /* pc_relative */
582 0, /* bitpos */
583 complain_overflow_dont, /* complain_on_overflow */
584 _bfd_mips_elf_generic_reloc, /* special_function */
585 "R_MIPS_SCN_DISP", /* name */
586 TRUE, /* partial_inplace */
587 0xffffffff, /* src_mask */
588 0xffffffff, /* dst_mask */
589 FALSE), /* pcrel_offset */
591 HOWTO (R_MIPS_REL16, /* type */
592 0, /* rightshift */
593 1, /* size (0 = byte, 1 = short, 2 = long) */
594 16, /* bitsize */
595 FALSE, /* pc_relative */
596 0, /* bitpos */
597 complain_overflow_signed, /* complain_on_overflow */
598 _bfd_mips_elf_generic_reloc, /* special_function */
599 "R_MIPS_REL16", /* name */
600 TRUE, /* partial_inplace */
601 0xffff, /* src_mask */
602 0xffff, /* dst_mask */
603 FALSE), /* pcrel_offset */
605 /* These two are obsolete. */
606 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
607 EMPTY_HOWTO (R_MIPS_PJUMP),
609 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
610 It must be used for multigot GOT's (and only there). */
611 HOWTO (R_MIPS_RELGOT, /* type */
612 0, /* rightshift */
613 2, /* size (0 = byte, 1 = short, 2 = long) */
614 32, /* bitsize */
615 FALSE, /* pc_relative */
616 0, /* bitpos */
617 complain_overflow_dont, /* complain_on_overflow */
618 _bfd_mips_elf_generic_reloc, /* special_function */
619 "R_MIPS_RELGOT", /* name */
620 TRUE, /* partial_inplace */
621 0xffffffff, /* src_mask */
622 0xffffffff, /* dst_mask */
623 FALSE), /* pcrel_offset */
625 /* Protected jump conversion. This is an optimization hint. No
626 relocation is required for correctness. */
627 HOWTO (R_MIPS_JALR, /* type */
628 0, /* rightshift */
629 2, /* size (0 = byte, 1 = short, 2 = long) */
630 32, /* bitsize */
631 FALSE, /* pc_relative */
632 0, /* bitpos */
633 complain_overflow_dont, /* complain_on_overflow */
634 _bfd_mips_elf_generic_reloc, /* special_function */
635 "R_MIPS_JALR", /* name */
636 FALSE, /* partial_inplace */
637 0, /* src_mask */
638 0x00000000, /* dst_mask */
639 FALSE), /* pcrel_offset */
641 /* TLS relocations. */
642 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
643 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
645 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
646 0, /* rightshift */
647 4, /* size (0 = byte, 1 = short, 2 = long) */
648 64, /* bitsize */
649 FALSE, /* pc_relative */
650 0, /* bitpos */
651 complain_overflow_dont, /* complain_on_overflow */
652 _bfd_mips_elf_generic_reloc, /* special_function */
653 "R_MIPS_TLS_DTPMOD64", /* name */
654 TRUE, /* partial_inplace */
655 MINUS_ONE, /* src_mask */
656 MINUS_ONE, /* dst_mask */
657 FALSE), /* pcrel_offset */
659 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
660 0, /* rightshift */
661 4, /* size (0 = byte, 1 = short, 2 = long) */
662 64, /* bitsize */
663 FALSE, /* pc_relative */
664 0, /* bitpos */
665 complain_overflow_dont, /* complain_on_overflow */
666 _bfd_mips_elf_generic_reloc, /* special_function */
667 "R_MIPS_TLS_DTPREL64", /* name */
668 TRUE, /* partial_inplace */
669 MINUS_ONE, /* src_mask */
670 MINUS_ONE, /* dst_mask */
671 FALSE), /* pcrel_offset */
673 /* TLS general dynamic variable reference. */
674 HOWTO (R_MIPS_TLS_GD, /* type */
675 0, /* rightshift */
676 2, /* size (0 = byte, 1 = short, 2 = long) */
677 16, /* bitsize */
678 FALSE, /* pc_relative */
679 0, /* bitpos */
680 complain_overflow_signed, /* complain_on_overflow */
681 _bfd_mips_elf_generic_reloc, /* special_function */
682 "R_MIPS_TLS_GD", /* name */
683 TRUE, /* partial_inplace */
684 0x0000ffff, /* src_mask */
685 0x0000ffff, /* dst_mask */
686 FALSE), /* pcrel_offset */
688 /* TLS local dynamic variable reference. */
689 HOWTO (R_MIPS_TLS_LDM, /* type */
690 0, /* rightshift */
691 2, /* size (0 = byte, 1 = short, 2 = long) */
692 16, /* bitsize */
693 FALSE, /* pc_relative */
694 0, /* bitpos */
695 complain_overflow_signed, /* complain_on_overflow */
696 _bfd_mips_elf_generic_reloc, /* special_function */
697 "R_MIPS_TLS_LDM", /* name */
698 TRUE, /* partial_inplace */
699 0x0000ffff, /* src_mask */
700 0x0000ffff, /* dst_mask */
701 FALSE), /* pcrel_offset */
703 /* TLS local dynamic offset. */
704 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
705 0, /* rightshift */
706 2, /* size (0 = byte, 1 = short, 2 = long) */
707 16, /* bitsize */
708 FALSE, /* pc_relative */
709 0, /* bitpos */
710 complain_overflow_signed, /* complain_on_overflow */
711 _bfd_mips_elf_generic_reloc, /* special_function */
712 "R_MIPS_TLS_DTPREL_HI16", /* name */
713 TRUE, /* partial_inplace */
714 0x0000ffff, /* src_mask */
715 0x0000ffff, /* dst_mask */
716 FALSE), /* pcrel_offset */
718 /* TLS local dynamic offset. */
719 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
720 0, /* rightshift */
721 2, /* size (0 = byte, 1 = short, 2 = long) */
722 16, /* bitsize */
723 FALSE, /* pc_relative */
724 0, /* bitpos */
725 complain_overflow_signed, /* complain_on_overflow */
726 _bfd_mips_elf_generic_reloc, /* special_function */
727 "R_MIPS_TLS_DTPREL_LO16", /* name */
728 TRUE, /* partial_inplace */
729 0x0000ffff, /* src_mask */
730 0x0000ffff, /* dst_mask */
731 FALSE), /* pcrel_offset */
733 /* TLS thread pointer offset. */
734 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
735 0, /* rightshift */
736 2, /* size (0 = byte, 1 = short, 2 = long) */
737 16, /* bitsize */
738 FALSE, /* pc_relative */
739 0, /* bitpos */
740 complain_overflow_signed, /* complain_on_overflow */
741 _bfd_mips_elf_generic_reloc, /* special_function */
742 "R_MIPS_TLS_GOTTPREL", /* name */
743 TRUE, /* partial_inplace */
744 0x0000ffff, /* src_mask */
745 0x0000ffff, /* dst_mask */
746 FALSE), /* pcrel_offset */
748 /* TLS IE dynamic relocations. */
749 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
751 HOWTO (R_MIPS_TLS_TPREL64, /* type */
752 0, /* rightshift */
753 4, /* size (0 = byte, 1 = short, 2 = long) */
754 64, /* bitsize */
755 FALSE, /* pc_relative */
756 0, /* bitpos */
757 complain_overflow_dont, /* complain_on_overflow */
758 _bfd_mips_elf_generic_reloc, /* special_function */
759 "R_MIPS_TLS_TPREL64", /* name */
760 TRUE, /* partial_inplace */
761 MINUS_ONE, /* src_mask */
762 MINUS_ONE, /* dst_mask */
763 FALSE), /* pcrel_offset */
765 /* TLS thread pointer offset. */
766 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
767 0, /* rightshift */
768 2, /* size (0 = byte, 1 = short, 2 = long) */
769 16, /* bitsize */
770 FALSE, /* pc_relative */
771 0, /* bitpos */
772 complain_overflow_signed, /* complain_on_overflow */
773 _bfd_mips_elf_generic_reloc, /* special_function */
774 "R_MIPS_TLS_TPREL_HI16", /* name */
775 TRUE, /* partial_inplace */
776 0x0000ffff, /* src_mask */
777 0x0000ffff, /* dst_mask */
778 FALSE), /* pcrel_offset */
780 /* TLS thread pointer offset. */
781 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
782 0, /* rightshift */
783 2, /* size (0 = byte, 1 = short, 2 = long) */
784 16, /* bitsize */
785 FALSE, /* pc_relative */
786 0, /* bitpos */
787 complain_overflow_signed, /* complain_on_overflow */
788 _bfd_mips_elf_generic_reloc, /* special_function */
789 "R_MIPS_TLS_TPREL_LO16", /* name */
790 TRUE, /* partial_inplace */
791 0x0000ffff, /* src_mask */
792 0x0000ffff, /* dst_mask */
793 FALSE), /* pcrel_offset */
796 /* The relocation table used for SHT_RELA sections. */
798 static reloc_howto_type mips_elf64_howto_table_rela[] =
800 /* No relocation. */
801 HOWTO (R_MIPS_NONE, /* type */
802 0, /* rightshift */
803 0, /* size (0 = byte, 1 = short, 2 = long) */
804 0, /* bitsize */
805 FALSE, /* pc_relative */
806 0, /* bitpos */
807 complain_overflow_dont, /* complain_on_overflow */
808 _bfd_mips_elf_generic_reloc, /* special_function */
809 "R_MIPS_NONE", /* name */
810 FALSE, /* partial_inplace */
811 0, /* src_mask */
812 0, /* dst_mask */
813 FALSE), /* pcrel_offset */
815 /* 16 bit relocation. */
816 HOWTO (R_MIPS_16, /* type */
817 0, /* rightshift */
818 2, /* size (0 = byte, 1 = short, 2 = long) */
819 16, /* bitsize */
820 FALSE, /* pc_relative */
821 0, /* bitpos */
822 complain_overflow_signed, /* complain_on_overflow */
823 _bfd_mips_elf_generic_reloc, /* special_function */
824 "R_MIPS_16", /* name */
825 FALSE, /* partial_inplace */
826 0, /* src_mask */
827 0x0000ffff, /* dst_mask */
828 FALSE), /* pcrel_offset */
830 /* 32 bit relocation. */
831 HOWTO (R_MIPS_32, /* type */
832 0, /* rightshift */
833 2, /* size (0 = byte, 1 = short, 2 = long) */
834 32, /* bitsize */
835 FALSE, /* pc_relative */
836 0, /* bitpos */
837 complain_overflow_dont, /* complain_on_overflow */
838 _bfd_mips_elf_generic_reloc, /* special_function */
839 "R_MIPS_32", /* name */
840 FALSE, /* partial_inplace */
841 0, /* src_mask */
842 0xffffffff, /* dst_mask */
843 FALSE), /* pcrel_offset */
845 /* 32 bit symbol relative relocation. */
846 HOWTO (R_MIPS_REL32, /* type */
847 0, /* rightshift */
848 2, /* size (0 = byte, 1 = short, 2 = long) */
849 32, /* bitsize */
850 FALSE, /* pc_relative */
851 0, /* bitpos */
852 complain_overflow_dont, /* complain_on_overflow */
853 _bfd_mips_elf_generic_reloc, /* special_function */
854 "R_MIPS_REL32", /* name */
855 FALSE, /* partial_inplace */
856 0, /* src_mask */
857 0xffffffff, /* dst_mask */
858 FALSE), /* pcrel_offset */
860 /* 26 bit jump address. */
861 HOWTO (R_MIPS_26, /* type */
862 2, /* rightshift */
863 2, /* size (0 = byte, 1 = short, 2 = long) */
864 26, /* bitsize */
865 FALSE, /* pc_relative */
866 0, /* bitpos */
867 complain_overflow_dont, /* complain_on_overflow */
868 /* This needs complex overflow
869 detection, because the upper 36
870 bits must match the PC + 4. */
871 _bfd_mips_elf_generic_reloc, /* special_function */
872 "R_MIPS_26", /* name */
873 FALSE, /* partial_inplace */
874 0, /* src_mask */
875 0x03ffffff, /* dst_mask */
876 FALSE), /* pcrel_offset */
878 /* High 16 bits of symbol value. */
879 HOWTO (R_MIPS_HI16, /* type */
880 0, /* rightshift */
881 2, /* size (0 = byte, 1 = short, 2 = long) */
882 16, /* bitsize */
883 FALSE, /* pc_relative */
884 0, /* bitpos */
885 complain_overflow_dont, /* complain_on_overflow */
886 _bfd_mips_elf_generic_reloc, /* special_function */
887 "R_MIPS_HI16", /* name */
888 FALSE, /* partial_inplace */
889 0, /* src_mask */
890 0x0000ffff, /* dst_mask */
891 FALSE), /* pcrel_offset */
893 /* Low 16 bits of symbol value. */
894 HOWTO (R_MIPS_LO16, /* type */
895 0, /* rightshift */
896 2, /* size (0 = byte, 1 = short, 2 = long) */
897 16, /* bitsize */
898 FALSE, /* pc_relative */
899 0, /* bitpos */
900 complain_overflow_dont, /* complain_on_overflow */
901 _bfd_mips_elf_generic_reloc, /* special_function */
902 "R_MIPS_LO16", /* name */
903 FALSE, /* partial_inplace */
904 0, /* src_mask */
905 0x0000ffff, /* dst_mask */
906 FALSE), /* pcrel_offset */
908 /* GP relative reference. */
909 HOWTO (R_MIPS_GPREL16, /* type */
910 0, /* rightshift */
911 2, /* size (0 = byte, 1 = short, 2 = long) */
912 16, /* bitsize */
913 FALSE, /* pc_relative */
914 0, /* bitpos */
915 complain_overflow_signed, /* complain_on_overflow */
916 mips_elf64_gprel16_reloc, /* special_function */
917 "R_MIPS_GPREL16", /* name */
918 FALSE, /* partial_inplace */
919 0, /* src_mask */
920 0x0000ffff, /* dst_mask */
921 FALSE), /* pcrel_offset */
923 /* Reference to literal section. */
924 HOWTO (R_MIPS_LITERAL, /* type */
925 0, /* rightshift */
926 2, /* size (0 = byte, 1 = short, 2 = long) */
927 16, /* bitsize */
928 FALSE, /* pc_relative */
929 0, /* bitpos */
930 complain_overflow_signed, /* complain_on_overflow */
931 mips_elf64_literal_reloc, /* special_function */
932 "R_MIPS_LITERAL", /* name */
933 FALSE, /* partial_inplace */
934 0, /* src_mask */
935 0x0000ffff, /* dst_mask */
936 FALSE), /* pcrel_offset */
938 /* Reference to global offset table. */
939 HOWTO (R_MIPS_GOT16, /* type */
940 0, /* rightshift */
941 2, /* size (0 = byte, 1 = short, 2 = long) */
942 16, /* bitsize */
943 FALSE, /* pc_relative */
944 0, /* bitpos */
945 complain_overflow_signed, /* complain_on_overflow */
946 _bfd_mips_elf_generic_reloc, /* special_function */
947 "R_MIPS_GOT16", /* name */
948 FALSE, /* partial_inplace */
949 0, /* src_mask */
950 0x0000ffff, /* dst_mask */
951 FALSE), /* pcrel_offset */
953 /* 16 bit PC relative reference. Note that the ABI document has a typo
954 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
955 We do the right thing here. */
956 HOWTO (R_MIPS_PC16, /* type */
957 2, /* rightshift */
958 2, /* size (0 = byte, 1 = short, 2 = long) */
959 16, /* bitsize */
960 TRUE, /* pc_relative */
961 0, /* bitpos */
962 complain_overflow_signed, /* complain_on_overflow */
963 _bfd_mips_elf_generic_reloc, /* special_function */
964 "R_MIPS_PC16", /* name */
965 FALSE, /* partial_inplace */
966 0, /* src_mask */
967 0x0000ffff, /* dst_mask */
968 TRUE), /* pcrel_offset */
970 /* 16 bit call through global offset table. */
971 HOWTO (R_MIPS_CALL16, /* type */
972 0, /* rightshift */
973 2, /* size (0 = byte, 1 = short, 2 = long) */
974 16, /* bitsize */
975 FALSE, /* pc_relative */
976 0, /* bitpos */
977 complain_overflow_signed, /* complain_on_overflow */
978 _bfd_mips_elf_generic_reloc, /* special_function */
979 "R_MIPS_CALL16", /* name */
980 FALSE, /* partial_inplace */
981 0, /* src_mask */
982 0x0000ffff, /* dst_mask */
983 FALSE), /* pcrel_offset */
985 /* 32 bit GP relative reference. */
986 HOWTO (R_MIPS_GPREL32, /* type */
987 0, /* rightshift */
988 2, /* size (0 = byte, 1 = short, 2 = long) */
989 32, /* bitsize */
990 FALSE, /* pc_relative */
991 0, /* bitpos */
992 complain_overflow_dont, /* complain_on_overflow */
993 mips_elf64_gprel32_reloc, /* special_function */
994 "R_MIPS_GPREL32", /* name */
995 FALSE, /* partial_inplace */
996 0, /* src_mask */
997 0xffffffff, /* dst_mask */
998 FALSE), /* pcrel_offset */
1000 EMPTY_HOWTO (13),
1001 EMPTY_HOWTO (14),
1002 EMPTY_HOWTO (15),
1004 /* A 5 bit shift field. */
1005 HOWTO (R_MIPS_SHIFT5, /* type */
1006 0, /* rightshift */
1007 2, /* size (0 = byte, 1 = short, 2 = long) */
1008 5, /* bitsize */
1009 FALSE, /* pc_relative */
1010 6, /* bitpos */
1011 complain_overflow_bitfield, /* complain_on_overflow */
1012 _bfd_mips_elf_generic_reloc, /* special_function */
1013 "R_MIPS_SHIFT5", /* name */
1014 FALSE, /* partial_inplace */
1015 0, /* src_mask */
1016 0x000007c0, /* dst_mask */
1017 FALSE), /* pcrel_offset */
1019 /* A 6 bit shift field. */
1020 HOWTO (R_MIPS_SHIFT6, /* type */
1021 0, /* rightshift */
1022 2, /* size (0 = byte, 1 = short, 2 = long) */
1023 6, /* bitsize */
1024 FALSE, /* pc_relative */
1025 6, /* bitpos */
1026 complain_overflow_bitfield, /* complain_on_overflow */
1027 mips_elf64_shift6_reloc, /* special_function */
1028 "R_MIPS_SHIFT6", /* name */
1029 FALSE, /* partial_inplace */
1030 0, /* src_mask */
1031 0x000007c4, /* dst_mask */
1032 FALSE), /* pcrel_offset */
1034 /* 64 bit relocation. */
1035 HOWTO (R_MIPS_64, /* type */
1036 0, /* rightshift */
1037 4, /* size (0 = byte, 1 = short, 2 = long) */
1038 64, /* bitsize */
1039 FALSE, /* pc_relative */
1040 0, /* bitpos */
1041 complain_overflow_dont, /* complain_on_overflow */
1042 _bfd_mips_elf_generic_reloc, /* special_function */
1043 "R_MIPS_64", /* name */
1044 FALSE, /* partial_inplace */
1045 0, /* src_mask */
1046 MINUS_ONE, /* dst_mask */
1047 FALSE), /* pcrel_offset */
1049 /* Displacement in the global offset table. */
1050 HOWTO (R_MIPS_GOT_DISP, /* type */
1051 0, /* rightshift */
1052 2, /* size (0 = byte, 1 = short, 2 = long) */
1053 16, /* bitsize */
1054 FALSE, /* pc_relative */
1055 0, /* bitpos */
1056 complain_overflow_signed, /* complain_on_overflow */
1057 _bfd_mips_elf_generic_reloc, /* special_function */
1058 "R_MIPS_GOT_DISP", /* name */
1059 FALSE, /* partial_inplace */
1060 0, /* src_mask */
1061 0x0000ffff, /* dst_mask */
1062 FALSE), /* pcrel_offset */
1064 /* Displacement to page pointer in the global offset table. */
1065 HOWTO (R_MIPS_GOT_PAGE, /* type */
1066 0, /* rightshift */
1067 2, /* size (0 = byte, 1 = short, 2 = long) */
1068 16, /* bitsize */
1069 FALSE, /* pc_relative */
1070 0, /* bitpos */
1071 complain_overflow_signed, /* complain_on_overflow */
1072 _bfd_mips_elf_generic_reloc, /* special_function */
1073 "R_MIPS_GOT_PAGE", /* name */
1074 FALSE, /* partial_inplace */
1075 0, /* src_mask */
1076 0x0000ffff, /* dst_mask */
1077 FALSE), /* pcrel_offset */
1079 /* Offset from page pointer in the global offset table. */
1080 HOWTO (R_MIPS_GOT_OFST, /* type */
1081 0, /* rightshift */
1082 2, /* size (0 = byte, 1 = short, 2 = long) */
1083 16, /* bitsize */
1084 FALSE, /* pc_relative */
1085 0, /* bitpos */
1086 complain_overflow_signed, /* complain_on_overflow */
1087 _bfd_mips_elf_generic_reloc, /* special_function */
1088 "R_MIPS_GOT_OFST", /* name */
1089 FALSE, /* partial_inplace */
1090 0, /* src_mask */
1091 0x0000ffff, /* dst_mask */
1092 FALSE), /* pcrel_offset */
1094 /* High 16 bits of displacement in global offset table. */
1095 HOWTO (R_MIPS_GOT_HI16, /* type */
1096 0, /* rightshift */
1097 2, /* size (0 = byte, 1 = short, 2 = long) */
1098 16, /* bitsize */
1099 FALSE, /* pc_relative */
1100 0, /* bitpos */
1101 complain_overflow_dont, /* complain_on_overflow */
1102 _bfd_mips_elf_generic_reloc, /* special_function */
1103 "R_MIPS_GOT_HI16", /* name */
1104 FALSE, /* partial_inplace */
1105 0, /* src_mask */
1106 0x0000ffff, /* dst_mask */
1107 FALSE), /* pcrel_offset */
1109 /* Low 16 bits of displacement in global offset table. */
1110 HOWTO (R_MIPS_GOT_LO16, /* type */
1111 0, /* rightshift */
1112 2, /* size (0 = byte, 1 = short, 2 = long) */
1113 16, /* bitsize */
1114 FALSE, /* pc_relative */
1115 0, /* bitpos */
1116 complain_overflow_dont, /* complain_on_overflow */
1117 _bfd_mips_elf_generic_reloc, /* special_function */
1118 "R_MIPS_GOT_LO16", /* name */
1119 FALSE, /* partial_inplace */
1120 0, /* src_mask */
1121 0x0000ffff, /* dst_mask */
1122 FALSE), /* pcrel_offset */
1124 /* 64 bit subtraction. */
1125 HOWTO (R_MIPS_SUB, /* type */
1126 0, /* rightshift */
1127 4, /* size (0 = byte, 1 = short, 2 = long) */
1128 64, /* bitsize */
1129 FALSE, /* pc_relative */
1130 0, /* bitpos */
1131 complain_overflow_dont, /* complain_on_overflow */
1132 _bfd_mips_elf_generic_reloc, /* special_function */
1133 "R_MIPS_SUB", /* name */
1134 FALSE, /* partial_inplace */
1135 0, /* src_mask */
1136 MINUS_ONE, /* dst_mask */
1137 FALSE), /* pcrel_offset */
1139 /* Insert the addend as an instruction. */
1140 /* FIXME: Not handled correctly. */
1141 HOWTO (R_MIPS_INSERT_A, /* type */
1142 0, /* rightshift */
1143 2, /* size (0 = byte, 1 = short, 2 = long) */
1144 32, /* bitsize */
1145 FALSE, /* pc_relative */
1146 0, /* bitpos */
1147 complain_overflow_dont, /* complain_on_overflow */
1148 _bfd_mips_elf_generic_reloc, /* special_function */
1149 "R_MIPS_INSERT_A", /* name */
1150 FALSE, /* partial_inplace */
1151 0, /* src_mask */
1152 0xffffffff, /* dst_mask */
1153 FALSE), /* pcrel_offset */
1155 /* Insert the addend as an instruction, and change all relocations
1156 to refer to the old instruction at the address. */
1157 /* FIXME: Not handled correctly. */
1158 HOWTO (R_MIPS_INSERT_B, /* type */
1159 0, /* rightshift */
1160 2, /* size (0 = byte, 1 = short, 2 = long) */
1161 32, /* bitsize */
1162 FALSE, /* pc_relative */
1163 0, /* bitpos */
1164 complain_overflow_dont, /* complain_on_overflow */
1165 _bfd_mips_elf_generic_reloc, /* special_function */
1166 "R_MIPS_INSERT_B", /* name */
1167 FALSE, /* partial_inplace */
1168 0, /* src_mask */
1169 0xffffffff, /* dst_mask */
1170 FALSE), /* pcrel_offset */
1172 /* Delete a 32 bit instruction. */
1173 /* FIXME: Not handled correctly. */
1174 HOWTO (R_MIPS_DELETE, /* type */
1175 0, /* rightshift */
1176 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 32, /* bitsize */
1178 FALSE, /* pc_relative */
1179 0, /* bitpos */
1180 complain_overflow_dont, /* complain_on_overflow */
1181 _bfd_mips_elf_generic_reloc, /* special_function */
1182 "R_MIPS_DELETE", /* name */
1183 FALSE, /* partial_inplace */
1184 0, /* src_mask */
1185 0xffffffff, /* dst_mask */
1186 FALSE), /* pcrel_offset */
1188 /* Get the higher value of a 64 bit addend. */
1189 HOWTO (R_MIPS_HIGHER, /* type */
1190 0, /* rightshift */
1191 2, /* size (0 = byte, 1 = short, 2 = long) */
1192 16, /* bitsize */
1193 FALSE, /* pc_relative */
1194 0, /* bitpos */
1195 complain_overflow_dont, /* complain_on_overflow */
1196 _bfd_mips_elf_generic_reloc, /* special_function */
1197 "R_MIPS_HIGHER", /* name */
1198 FALSE, /* partial_inplace */
1199 0, /* src_mask */
1200 0x0000ffff, /* dst_mask */
1201 FALSE), /* pcrel_offset */
1203 /* Get the highest value of a 64 bit addend. */
1204 HOWTO (R_MIPS_HIGHEST, /* type */
1205 0, /* rightshift */
1206 2, /* size (0 = byte, 1 = short, 2 = long) */
1207 16, /* bitsize */
1208 FALSE, /* pc_relative */
1209 0, /* bitpos */
1210 complain_overflow_dont, /* complain_on_overflow */
1211 _bfd_mips_elf_generic_reloc, /* special_function */
1212 "R_MIPS_HIGHEST", /* name */
1213 FALSE, /* partial_inplace */
1214 0, /* src_mask */
1215 0x0000ffff, /* dst_mask */
1216 FALSE), /* pcrel_offset */
1218 /* High 16 bits of displacement in global offset table. */
1219 HOWTO (R_MIPS_CALL_HI16, /* type */
1220 0, /* rightshift */
1221 2, /* size (0 = byte, 1 = short, 2 = long) */
1222 16, /* bitsize */
1223 FALSE, /* pc_relative */
1224 0, /* bitpos */
1225 complain_overflow_dont, /* complain_on_overflow */
1226 _bfd_mips_elf_generic_reloc, /* special_function */
1227 "R_MIPS_CALL_HI16", /* name */
1228 FALSE, /* partial_inplace */
1229 0, /* src_mask */
1230 0x0000ffff, /* dst_mask */
1231 FALSE), /* pcrel_offset */
1233 /* Low 16 bits of displacement in global offset table. */
1234 HOWTO (R_MIPS_CALL_LO16, /* type */
1235 0, /* rightshift */
1236 2, /* size (0 = byte, 1 = short, 2 = long) */
1237 16, /* bitsize */
1238 FALSE, /* pc_relative */
1239 0, /* bitpos */
1240 complain_overflow_dont, /* complain_on_overflow */
1241 _bfd_mips_elf_generic_reloc, /* special_function */
1242 "R_MIPS_CALL_LO16", /* name */
1243 FALSE, /* partial_inplace */
1244 0, /* src_mask */
1245 0x0000ffff, /* dst_mask */
1246 FALSE), /* pcrel_offset */
1248 /* Section displacement, used by an associated event location section. */
1249 HOWTO (R_MIPS_SCN_DISP, /* type */
1250 0, /* rightshift */
1251 2, /* size (0 = byte, 1 = short, 2 = long) */
1252 32, /* bitsize */
1253 FALSE, /* pc_relative */
1254 0, /* bitpos */
1255 complain_overflow_dont, /* complain_on_overflow */
1256 _bfd_mips_elf_generic_reloc, /* special_function */
1257 "R_MIPS_SCN_DISP", /* name */
1258 FALSE, /* partial_inplace */
1259 0, /* src_mask */
1260 0xffffffff, /* dst_mask */
1261 FALSE), /* pcrel_offset */
1263 HOWTO (R_MIPS_REL16, /* type */
1264 0, /* rightshift */
1265 1, /* size (0 = byte, 1 = short, 2 = long) */
1266 16, /* bitsize */
1267 FALSE, /* pc_relative */
1268 0, /* bitpos */
1269 complain_overflow_signed, /* complain_on_overflow */
1270 _bfd_mips_elf_generic_reloc, /* special_function */
1271 "R_MIPS_REL16", /* name */
1272 FALSE, /* partial_inplace */
1273 0, /* src_mask */
1274 0xffff, /* dst_mask */
1275 FALSE), /* pcrel_offset */
1277 /* These two are obsolete. */
1278 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1279 EMPTY_HOWTO (R_MIPS_PJUMP),
1281 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1282 It must be used for multigot GOT's (and only there). */
1283 HOWTO (R_MIPS_RELGOT, /* type */
1284 0, /* rightshift */
1285 2, /* size (0 = byte, 1 = short, 2 = long) */
1286 32, /* bitsize */
1287 FALSE, /* pc_relative */
1288 0, /* bitpos */
1289 complain_overflow_dont, /* complain_on_overflow */
1290 _bfd_mips_elf_generic_reloc, /* special_function */
1291 "R_MIPS_RELGOT", /* name */
1292 FALSE, /* partial_inplace */
1293 0, /* src_mask */
1294 0xffffffff, /* dst_mask */
1295 FALSE), /* pcrel_offset */
1297 /* Protected jump conversion. This is an optimization hint. No
1298 relocation is required for correctness. */
1299 HOWTO (R_MIPS_JALR, /* type */
1300 0, /* rightshift */
1301 2, /* size (0 = byte, 1 = short, 2 = long) */
1302 32, /* bitsize */
1303 FALSE, /* pc_relative */
1304 0, /* bitpos */
1305 complain_overflow_dont, /* complain_on_overflow */
1306 _bfd_mips_elf_generic_reloc, /* special_function */
1307 "R_MIPS_JALR", /* name */
1308 FALSE, /* partial_inplace */
1309 0, /* src_mask */
1310 0x00000000, /* dst_mask */
1311 FALSE), /* pcrel_offset */
1313 /* TLS relocations. */
1314 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1315 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1316 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1317 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
1319 /* TLS general dynamic variable reference. */
1320 HOWTO (R_MIPS_TLS_GD, /* type */
1321 0, /* rightshift */
1322 2, /* size (0 = byte, 1 = short, 2 = long) */
1323 16, /* bitsize */
1324 FALSE, /* pc_relative */
1325 0, /* bitpos */
1326 complain_overflow_signed, /* complain_on_overflow */
1327 _bfd_mips_elf_generic_reloc, /* special_function */
1328 "R_MIPS_TLS_GD", /* name */
1329 TRUE, /* partial_inplace */
1330 0x0000ffff, /* src_mask */
1331 0x0000ffff, /* dst_mask */
1332 FALSE), /* pcrel_offset */
1334 /* TLS local dynamic variable reference. */
1335 HOWTO (R_MIPS_TLS_LDM, /* type */
1336 0, /* rightshift */
1337 2, /* size (0 = byte, 1 = short, 2 = long) */
1338 16, /* bitsize */
1339 FALSE, /* pc_relative */
1340 0, /* bitpos */
1341 complain_overflow_signed, /* complain_on_overflow */
1342 _bfd_mips_elf_generic_reloc, /* special_function */
1343 "R_MIPS_TLS_LDM", /* name */
1344 TRUE, /* partial_inplace */
1345 0x0000ffff, /* src_mask */
1346 0x0000ffff, /* dst_mask */
1347 FALSE), /* pcrel_offset */
1349 /* TLS local dynamic offset. */
1350 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1351 0, /* rightshift */
1352 2, /* size (0 = byte, 1 = short, 2 = long) */
1353 16, /* bitsize */
1354 FALSE, /* pc_relative */
1355 0, /* bitpos */
1356 complain_overflow_signed, /* complain_on_overflow */
1357 _bfd_mips_elf_generic_reloc, /* special_function */
1358 "R_MIPS_TLS_DTPREL_HI16", /* name */
1359 TRUE, /* partial_inplace */
1360 0x0000ffff, /* src_mask */
1361 0x0000ffff, /* dst_mask */
1362 FALSE), /* pcrel_offset */
1364 /* TLS local dynamic offset. */
1365 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1366 0, /* rightshift */
1367 2, /* size (0 = byte, 1 = short, 2 = long) */
1368 16, /* bitsize */
1369 FALSE, /* pc_relative */
1370 0, /* bitpos */
1371 complain_overflow_signed, /* complain_on_overflow */
1372 _bfd_mips_elf_generic_reloc, /* special_function */
1373 "R_MIPS_TLS_DTPREL_LO16", /* name */
1374 TRUE, /* partial_inplace */
1375 0x0000ffff, /* src_mask */
1376 0x0000ffff, /* dst_mask */
1377 FALSE), /* pcrel_offset */
1379 /* TLS thread pointer offset. */
1380 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1381 0, /* rightshift */
1382 2, /* size (0 = byte, 1 = short, 2 = long) */
1383 16, /* bitsize */
1384 FALSE, /* pc_relative */
1385 0, /* bitpos */
1386 complain_overflow_signed, /* complain_on_overflow */
1387 _bfd_mips_elf_generic_reloc, /* special_function */
1388 "R_MIPS_TLS_GOTTPREL", /* name */
1389 TRUE, /* partial_inplace */
1390 0x0000ffff, /* src_mask */
1391 0x0000ffff, /* dst_mask */
1392 FALSE), /* pcrel_offset */
1394 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1395 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1397 /* TLS thread pointer offset. */
1398 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1399 0, /* rightshift */
1400 2, /* size (0 = byte, 1 = short, 2 = long) */
1401 16, /* bitsize */
1402 FALSE, /* pc_relative */
1403 0, /* bitpos */
1404 complain_overflow_signed, /* complain_on_overflow */
1405 _bfd_mips_elf_generic_reloc, /* special_function */
1406 "R_MIPS_TLS_TPREL_HI16", /* name */
1407 TRUE, /* partial_inplace */
1408 0x0000ffff, /* src_mask */
1409 0x0000ffff, /* dst_mask */
1410 FALSE), /* pcrel_offset */
1412 /* TLS thread pointer offset. */
1413 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1414 0, /* rightshift */
1415 2, /* size (0 = byte, 1 = short, 2 = long) */
1416 16, /* bitsize */
1417 FALSE, /* pc_relative */
1418 0, /* bitpos */
1419 complain_overflow_signed, /* complain_on_overflow */
1420 _bfd_mips_elf_generic_reloc, /* special_function */
1421 "R_MIPS_TLS_TPREL_LO16", /* name */
1422 TRUE, /* partial_inplace */
1423 0x0000ffff, /* src_mask */
1424 0x0000ffff, /* dst_mask */
1425 FALSE), /* pcrel_offset */
1428 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1430 /* The reloc used for the mips16 jump instruction. */
1431 HOWTO (R_MIPS16_26, /* type */
1432 2, /* rightshift */
1433 2, /* size (0 = byte, 1 = short, 2 = long) */
1434 26, /* bitsize */
1435 FALSE, /* pc_relative */
1436 0, /* bitpos */
1437 complain_overflow_dont, /* complain_on_overflow */
1438 /* This needs complex overflow
1439 detection, because the upper four
1440 bits must match the PC. */
1441 mips16_jump_reloc, /* special_function */
1442 "R_MIPS16_26", /* name */
1443 TRUE, /* partial_inplace */
1444 0x3ffffff, /* src_mask */
1445 0x3ffffff, /* dst_mask */
1446 FALSE), /* pcrel_offset */
1448 /* The reloc used for the mips16 gprel instruction. */
1449 HOWTO (R_MIPS16_GPREL, /* type */
1450 0, /* rightshift */
1451 2, /* size (0 = byte, 1 = short, 2 = long) */
1452 16, /* bitsize */
1453 FALSE, /* pc_relative */
1454 0, /* bitpos */
1455 complain_overflow_signed, /* complain_on_overflow */
1456 mips16_gprel_reloc, /* special_function */
1457 "R_MIPS16_GPREL", /* name */
1458 TRUE, /* partial_inplace */
1459 0x0000ffff, /* src_mask */
1460 0x0000ffff, /* dst_mask */
1461 FALSE), /* pcrel_offset */
1463 /* A placeholder for MIPS16 reference to global offset table. */
1464 EMPTY_HOWTO (R_MIPS16_GOT16),
1466 /* A placeholder for MIPS16 16 bit call through global offset table. */
1467 EMPTY_HOWTO (R_MIPS16_CALL16),
1469 /* MIPS16 high 16 bits of symbol value. */
1470 HOWTO (R_MIPS16_HI16, /* type */
1471 16, /* rightshift */
1472 2, /* size (0 = byte, 1 = short, 2 = long) */
1473 16, /* bitsize */
1474 FALSE, /* pc_relative */
1475 0, /* bitpos */
1476 complain_overflow_dont, /* complain_on_overflow */
1477 _bfd_mips_elf_hi16_reloc, /* special_function */
1478 "R_MIPS16_HI16", /* name */
1479 TRUE, /* partial_inplace */
1480 0x0000ffff, /* src_mask */
1481 0x0000ffff, /* dst_mask */
1482 FALSE), /* pcrel_offset */
1484 /* MIPS16 low 16 bits of symbol value. */
1485 HOWTO (R_MIPS16_LO16, /* type */
1486 0, /* rightshift */
1487 2, /* size (0 = byte, 1 = short, 2 = long) */
1488 16, /* bitsize */
1489 FALSE, /* pc_relative */
1490 0, /* bitpos */
1491 complain_overflow_dont, /* complain_on_overflow */
1492 _bfd_mips_elf_lo16_reloc, /* special_function */
1493 "R_MIPS16_LO16", /* name */
1494 TRUE, /* partial_inplace */
1495 0x0000ffff, /* src_mask */
1496 0x0000ffff, /* dst_mask */
1497 FALSE), /* pcrel_offset */
1500 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1502 /* The reloc used for the mips16 jump instruction. */
1503 HOWTO (R_MIPS16_26, /* type */
1504 2, /* rightshift */
1505 2, /* size (0 = byte, 1 = short, 2 = long) */
1506 26, /* bitsize */
1507 FALSE, /* pc_relative */
1508 0, /* bitpos */
1509 complain_overflow_dont, /* complain_on_overflow */
1510 /* This needs complex overflow
1511 detection, because the upper four
1512 bits must match the PC. */
1513 mips16_jump_reloc, /* special_function */
1514 "R_MIPS16_26", /* name */
1515 FALSE, /* partial_inplace */
1516 0x3ffffff, /* src_mask */
1517 0x3ffffff, /* dst_mask */
1518 FALSE), /* pcrel_offset */
1520 /* The reloc used for the mips16 gprel instruction. */
1521 HOWTO (R_MIPS16_GPREL, /* type */
1522 0, /* rightshift */
1523 2, /* size (0 = byte, 1 = short, 2 = long) */
1524 16, /* bitsize */
1525 FALSE, /* pc_relative */
1526 0, /* bitpos */
1527 complain_overflow_signed, /* complain_on_overflow */
1528 mips16_gprel_reloc, /* special_function */
1529 "R_MIPS16_GPREL", /* name */
1530 FALSE, /* partial_inplace */
1531 0x0000ffff, /* src_mask */
1532 0x0000ffff, /* dst_mask */
1533 FALSE), /* pcrel_offset */
1535 /* A placeholder for MIPS16 reference to global offset table. */
1536 EMPTY_HOWTO (R_MIPS16_GOT16),
1538 /* A placeholder for MIPS16 16 bit call through global offset table. */
1539 EMPTY_HOWTO (R_MIPS16_CALL16),
1541 /* MIPS16 high 16 bits of symbol value. */
1542 HOWTO (R_MIPS16_HI16, /* type */
1543 16, /* rightshift */
1544 2, /* size (0 = byte, 1 = short, 2 = long) */
1545 16, /* bitsize */
1546 FALSE, /* pc_relative */
1547 0, /* bitpos */
1548 complain_overflow_dont, /* complain_on_overflow */
1549 _bfd_mips_elf_hi16_reloc, /* special_function */
1550 "R_MIPS16_HI16", /* name */
1551 FALSE, /* partial_inplace */
1552 0x0000ffff, /* src_mask */
1553 0x0000ffff, /* dst_mask */
1554 FALSE), /* pcrel_offset */
1556 /* MIPS16 low 16 bits of symbol value. */
1557 HOWTO (R_MIPS16_LO16, /* type */
1558 0, /* rightshift */
1559 2, /* size (0 = byte, 1 = short, 2 = long) */
1560 16, /* bitsize */
1561 FALSE, /* pc_relative */
1562 0, /* bitpos */
1563 complain_overflow_dont, /* complain_on_overflow */
1564 _bfd_mips_elf_lo16_reloc, /* special_function */
1565 "R_MIPS16_LO16", /* name */
1566 FALSE, /* partial_inplace */
1567 0x0000ffff, /* src_mask */
1568 0x0000ffff, /* dst_mask */
1569 FALSE), /* pcrel_offset */
1572 /* GNU extension to record C++ vtable hierarchy */
1573 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1574 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1575 0, /* rightshift */
1576 2, /* size (0 = byte, 1 = short, 2 = long) */
1577 0, /* bitsize */
1578 FALSE, /* pc_relative */
1579 0, /* bitpos */
1580 complain_overflow_dont, /* complain_on_overflow */
1581 NULL, /* special_function */
1582 "R_MIPS_GNU_VTINHERIT", /* name */
1583 FALSE, /* partial_inplace */
1584 0, /* src_mask */
1585 0, /* dst_mask */
1586 FALSE); /* pcrel_offset */
1588 /* GNU extension to record C++ vtable member usage */
1589 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1590 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1591 0, /* rightshift */
1592 2, /* size (0 = byte, 1 = short, 2 = long) */
1593 0, /* bitsize */
1594 FALSE, /* pc_relative */
1595 0, /* bitpos */
1596 complain_overflow_dont, /* complain_on_overflow */
1597 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1598 "R_MIPS_GNU_VTENTRY", /* name */
1599 FALSE, /* partial_inplace */
1600 0, /* src_mask */
1601 0, /* dst_mask */
1602 FALSE); /* pcrel_offset */
1604 /* 16 bit offset for pc-relative branches. */
1605 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1606 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1607 2, /* rightshift */
1608 2, /* size (0 = byte, 1 = short, 2 = long) */
1609 16, /* bitsize */
1610 TRUE, /* pc_relative */
1611 0, /* bitpos */
1612 complain_overflow_signed, /* complain_on_overflow */
1613 _bfd_mips_elf_generic_reloc, /* special_function */
1614 "R_MIPS_GNU_REL16_S2", /* name */
1615 TRUE, /* partial_inplace */
1616 0x0000ffff, /* src_mask */
1617 0x0000ffff, /* dst_mask */
1618 TRUE); /* pcrel_offset */
1620 /* 16 bit offset for pc-relative branches. */
1621 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1622 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1623 2, /* rightshift */
1624 2, /* size (0 = byte, 1 = short, 2 = long) */
1625 16, /* bitsize */
1626 TRUE, /* pc_relative */
1627 0, /* bitpos */
1628 complain_overflow_signed, /* complain_on_overflow */
1629 _bfd_mips_elf_generic_reloc, /* special_function */
1630 "R_MIPS_GNU_REL16_S2", /* name */
1631 FALSE, /* partial_inplace */
1632 0, /* src_mask */
1633 0x0000ffff, /* dst_mask */
1634 TRUE); /* pcrel_offset */
1636 /* Swap in a MIPS 64-bit Rel reloc. */
1638 static void
1639 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1640 Elf64_Mips_Internal_Rela *dst)
1642 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1643 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1644 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1645 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1646 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1647 dst->r_type = H_GET_8 (abfd, src->r_type);
1648 dst->r_addend = 0;
1651 /* Swap in a MIPS 64-bit Rela reloc. */
1653 static void
1654 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1655 Elf64_Mips_Internal_Rela *dst)
1657 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1658 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1659 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1660 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1661 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1662 dst->r_type = H_GET_8 (abfd, src->r_type);
1663 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1666 /* Swap out a MIPS 64-bit Rel reloc. */
1668 static void
1669 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1670 Elf64_Mips_External_Rel *dst)
1672 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1673 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1674 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1675 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1676 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1677 H_PUT_8 (abfd, src->r_type, dst->r_type);
1680 /* Swap out a MIPS 64-bit Rela reloc. */
1682 static void
1683 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1684 Elf64_Mips_External_Rela *dst)
1686 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1687 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1688 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1689 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1690 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1691 H_PUT_8 (abfd, src->r_type, dst->r_type);
1692 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1695 /* Swap in a MIPS 64-bit Rel reloc. */
1697 static void
1698 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1699 Elf_Internal_Rela *dst)
1701 Elf64_Mips_Internal_Rela mirel;
1703 mips_elf64_swap_reloc_in (abfd,
1704 (const Elf64_Mips_External_Rel *) src,
1705 &mirel);
1707 dst[0].r_offset = mirel.r_offset;
1708 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1709 dst[0].r_addend = 0;
1710 dst[1].r_offset = mirel.r_offset;
1711 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1712 dst[1].r_addend = 0;
1713 dst[2].r_offset = mirel.r_offset;
1714 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1715 dst[2].r_addend = 0;
1718 /* Swap in a MIPS 64-bit Rela reloc. */
1720 static void
1721 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1722 Elf_Internal_Rela *dst)
1724 Elf64_Mips_Internal_Rela mirela;
1726 mips_elf64_swap_reloca_in (abfd,
1727 (const Elf64_Mips_External_Rela *) src,
1728 &mirela);
1730 dst[0].r_offset = mirela.r_offset;
1731 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1732 dst[0].r_addend = mirela.r_addend;
1733 dst[1].r_offset = mirela.r_offset;
1734 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1735 dst[1].r_addend = 0;
1736 dst[2].r_offset = mirela.r_offset;
1737 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1738 dst[2].r_addend = 0;
1741 /* Swap out a MIPS 64-bit Rel reloc. */
1743 static void
1744 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1745 bfd_byte *dst)
1747 Elf64_Mips_Internal_Rela mirel;
1749 mirel.r_offset = src[0].r_offset;
1750 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1752 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1753 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1754 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1755 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1756 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1758 mips_elf64_swap_reloc_out (abfd, &mirel,
1759 (Elf64_Mips_External_Rel *) dst);
1762 /* Swap out a MIPS 64-bit Rela reloc. */
1764 static void
1765 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1766 bfd_byte *dst)
1768 Elf64_Mips_Internal_Rela mirela;
1770 mirela.r_offset = src[0].r_offset;
1771 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1772 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1774 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1775 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1776 mirela.r_addend = src[0].r_addend;
1777 BFD_ASSERT(src[1].r_addend == 0);
1778 BFD_ASSERT(src[2].r_addend == 0);
1780 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1781 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1782 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1784 mips_elf64_swap_reloca_out (abfd, &mirela,
1785 (Elf64_Mips_External_Rela *) dst);
1788 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1789 dangerous relocation. */
1791 static bfd_boolean
1792 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1794 unsigned int count;
1795 asymbol **sym;
1796 unsigned int i;
1798 /* If we've already figured out what GP will be, just return it. */
1799 *pgp = _bfd_get_gp_value (output_bfd);
1800 if (*pgp)
1801 return TRUE;
1803 count = bfd_get_symcount (output_bfd);
1804 sym = bfd_get_outsymbols (output_bfd);
1806 /* The linker script will have created a symbol named `_gp' with the
1807 appropriate value. */
1808 if (sym == NULL)
1809 i = count;
1810 else
1812 for (i = 0; i < count; i++, sym++)
1814 register const char *name;
1816 name = bfd_asymbol_name (*sym);
1817 if (*name == '_' && strcmp (name, "_gp") == 0)
1819 *pgp = bfd_asymbol_value (*sym);
1820 _bfd_set_gp_value (output_bfd, *pgp);
1821 break;
1826 if (i >= count)
1828 /* Only get the error once. */
1829 *pgp = 4;
1830 _bfd_set_gp_value (output_bfd, *pgp);
1831 return FALSE;
1834 return TRUE;
1837 /* We have to figure out the gp value, so that we can adjust the
1838 symbol value correctly. We look up the symbol _gp in the output
1839 BFD. If we can't find it, we're stuck. We cache it in the ELF
1840 target data. We don't need to adjust the symbol value for an
1841 external symbol if we are producing relocatable output. */
1843 static bfd_reloc_status_type
1844 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1845 char **error_message, bfd_vma *pgp)
1847 if (bfd_is_und_section (symbol->section)
1848 && ! relocatable)
1850 *pgp = 0;
1851 return bfd_reloc_undefined;
1854 *pgp = _bfd_get_gp_value (output_bfd);
1855 if (*pgp == 0
1856 && (! relocatable
1857 || (symbol->flags & BSF_SECTION_SYM) != 0))
1859 if (relocatable)
1861 /* Make up a value. */
1862 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1863 _bfd_set_gp_value (output_bfd, *pgp);
1865 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1867 *error_message =
1868 (char *) _("GP relative relocation when _gp not defined");
1869 return bfd_reloc_dangerous;
1873 return bfd_reloc_ok;
1876 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1877 become the offset from the gp register. */
1879 static bfd_reloc_status_type
1880 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1881 void *data, asection *input_section, bfd *output_bfd,
1882 char **error_message)
1884 bfd_boolean relocatable;
1885 bfd_reloc_status_type ret;
1886 bfd_vma gp;
1888 /* If we're relocating, and this is an external symbol, we don't want
1889 to change anything. */
1890 if (output_bfd != NULL
1891 && (symbol->flags & BSF_SECTION_SYM) == 0
1892 && (symbol->flags & BSF_LOCAL) != 0)
1894 reloc_entry->address += input_section->output_offset;
1895 return bfd_reloc_ok;
1898 if (output_bfd != NULL)
1899 relocatable = TRUE;
1900 else
1902 relocatable = FALSE;
1903 output_bfd = symbol->section->output_section->owner;
1906 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1907 &gp);
1908 if (ret != bfd_reloc_ok)
1909 return ret;
1911 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1912 input_section, relocatable,
1913 data, gp);
1916 /* Do a R_MIPS_LITERAL relocation. */
1918 static bfd_reloc_status_type
1919 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1920 void *data, asection *input_section, bfd *output_bfd,
1921 char **error_message)
1923 bfd_boolean relocatable;
1924 bfd_reloc_status_type ret;
1925 bfd_vma gp;
1927 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
1928 if (output_bfd != NULL
1929 && (symbol->flags & BSF_SECTION_SYM) == 0
1930 && (symbol->flags & BSF_LOCAL) != 0)
1932 *error_message = (char *)
1933 _("literal relocation occurs for an external symbol");
1934 return bfd_reloc_outofrange;
1937 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1938 if (output_bfd != NULL)
1939 relocatable = TRUE;
1940 else
1942 relocatable = FALSE;
1943 output_bfd = symbol->section->output_section->owner;
1946 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1947 &gp);
1948 if (ret != bfd_reloc_ok)
1949 return ret;
1951 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1952 input_section, relocatable,
1953 data, gp);
1956 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1957 become the offset from the gp register. */
1959 static bfd_reloc_status_type
1960 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1961 void *data, asection *input_section, bfd *output_bfd,
1962 char **error_message)
1964 bfd_boolean relocatable;
1965 bfd_reloc_status_type ret;
1966 bfd_vma gp;
1967 bfd_vma relocation;
1968 bfd_vma val;
1970 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1971 if (output_bfd != NULL
1972 && (symbol->flags & BSF_SECTION_SYM) == 0
1973 && (symbol->flags & BSF_LOCAL) != 0)
1975 *error_message = (char *)
1976 _("32bits gp relative relocation occurs for an external symbol");
1977 return bfd_reloc_outofrange;
1980 if (output_bfd != NULL)
1981 relocatable = TRUE;
1982 else
1984 relocatable = FALSE;
1985 output_bfd = symbol->section->output_section->owner;
1988 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
1989 error_message, &gp);
1990 if (ret != bfd_reloc_ok)
1991 return ret;
1993 if (bfd_is_com_section (symbol->section))
1994 relocation = 0;
1995 else
1996 relocation = symbol->value;
1998 relocation += symbol->section->output_section->vma;
1999 relocation += symbol->section->output_offset;
2001 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2002 return bfd_reloc_outofrange;
2004 /* Set val to the offset into the section or symbol. */
2005 val = reloc_entry->addend;
2007 if (reloc_entry->howto->partial_inplace)
2008 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2010 /* Adjust val for the final section location and GP value. If we
2011 are producing relocatable output, we don't want to do this for
2012 an external symbol. */
2013 if (! relocatable
2014 || (symbol->flags & BSF_SECTION_SYM) != 0)
2015 val += relocation - gp;
2017 if (reloc_entry->howto->partial_inplace)
2018 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2019 else
2020 reloc_entry->addend = val;
2022 if (relocatable)
2023 reloc_entry->address += input_section->output_offset;
2025 return bfd_reloc_ok;
2028 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2029 the rest is at bits 6-10. The bitpos already got right by the howto. */
2031 static bfd_reloc_status_type
2032 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2033 void *data, asection *input_section, bfd *output_bfd,
2034 char **error_message)
2036 if (reloc_entry->howto->partial_inplace)
2038 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2039 | (reloc_entry->addend & 0x00000800) >> 9);
2042 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2043 input_section, output_bfd,
2044 error_message);
2047 /* Handle a mips16 jump. */
2049 static bfd_reloc_status_type
2050 mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
2051 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
2052 asection *input_section, bfd *output_bfd,
2053 char **error_message ATTRIBUTE_UNUSED)
2055 if (output_bfd != NULL
2056 && (symbol->flags & BSF_SECTION_SYM) == 0
2057 && (! reloc_entry->howto->partial_inplace
2058 || reloc_entry->addend == 0))
2060 reloc_entry->address += input_section->output_offset;
2061 return bfd_reloc_ok;
2064 /* FIXME. */
2066 static bfd_boolean warned;
2068 if (! warned)
2069 (*_bfd_error_handler)
2070 (_("Linking mips16 objects into %s format is not supported"),
2071 bfd_get_target (input_section->output_section->owner));
2072 warned = TRUE;
2075 return bfd_reloc_undefined;
2078 /* Handle a mips16 GP relative reloc. */
2080 static bfd_reloc_status_type
2081 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2082 void *data, asection *input_section, bfd *output_bfd,
2083 char **error_message)
2085 bfd_boolean relocatable;
2086 bfd_reloc_status_type ret;
2087 bfd_byte *location;
2088 bfd_vma gp;
2090 /* If we're relocating, and this is an external symbol, we don't want
2091 to change anything. */
2092 if (output_bfd != NULL
2093 && (symbol->flags & BSF_SECTION_SYM) == 0
2094 && (symbol->flags & BSF_LOCAL) != 0)
2096 reloc_entry->address += input_section->output_offset;
2097 return bfd_reloc_ok;
2100 if (output_bfd != NULL)
2101 relocatable = TRUE;
2102 else
2104 relocatable = FALSE;
2105 output_bfd = symbol->section->output_section->owner;
2108 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2109 &gp);
2110 if (ret != bfd_reloc_ok)
2111 return ret;
2113 location = (bfd_byte *) data + reloc_entry->address;
2114 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2115 location);
2116 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2117 input_section, relocatable,
2118 data, gp);
2119 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2120 location);
2122 return ret;
2125 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2127 struct elf_reloc_map {
2128 bfd_reloc_code_real_type bfd_val;
2129 enum elf_mips_reloc_type elf_val;
2132 static const struct elf_reloc_map mips_reloc_map[] =
2134 { BFD_RELOC_NONE, R_MIPS_NONE },
2135 { BFD_RELOC_16, R_MIPS_16 },
2136 { BFD_RELOC_32, R_MIPS_32 },
2137 /* There is no BFD reloc for R_MIPS_REL32. */
2138 { BFD_RELOC_64, R_MIPS_64 },
2139 { BFD_RELOC_CTOR, R_MIPS_64 },
2140 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
2141 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2142 { BFD_RELOC_LO16, R_MIPS_LO16 },
2143 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2144 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2145 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2146 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2147 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2148 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2149 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2150 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2151 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2152 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2153 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2154 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2155 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2156 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2157 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2158 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2159 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2160 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2161 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2162 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2163 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2164 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2165 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2166 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2167 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2168 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2169 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2170 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2171 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2172 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2173 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2174 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2175 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2176 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2177 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2178 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2179 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2180 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2181 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2184 static const struct elf_reloc_map mips16_reloc_map[] =
2186 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2187 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2188 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2189 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2192 /* Given a BFD reloc type, return a howto structure. */
2194 static reloc_howto_type *
2195 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2196 bfd_reloc_code_real_type code)
2198 unsigned int i;
2199 /* FIXME: We default to RELA here instead of choosing the right
2200 relocation variant. */
2201 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
2202 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
2204 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2205 i++)
2207 if (mips_reloc_map[i].bfd_val == code)
2208 return &howto_table[(int) mips_reloc_map[i].elf_val];
2211 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2212 i++)
2214 if (mips16_reloc_map[i].bfd_val == code)
2215 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2218 switch (code)
2220 case BFD_RELOC_VTABLE_INHERIT:
2221 return &elf_mips_gnu_vtinherit_howto;
2222 case BFD_RELOC_VTABLE_ENTRY:
2223 return &elf_mips_gnu_vtentry_howto;
2224 default:
2225 bfd_set_error (bfd_error_bad_value);
2226 return NULL;
2230 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2232 static reloc_howto_type *
2233 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2235 switch (r_type)
2237 case R_MIPS_GNU_VTINHERIT:
2238 return &elf_mips_gnu_vtinherit_howto;
2239 case R_MIPS_GNU_VTENTRY:
2240 return &elf_mips_gnu_vtentry_howto;
2241 case R_MIPS_GNU_REL16_S2:
2242 if (rela_p)
2243 return &elf_mips_gnu_rela16_s2;
2244 else
2245 return &elf_mips_gnu_rel16_s2;
2246 default:
2247 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2249 if (rela_p)
2250 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2251 else
2252 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2254 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2255 if (rela_p)
2256 return &mips_elf64_howto_table_rela[r_type];
2257 else
2258 return &mips_elf64_howto_table_rel[r_type];
2259 break;
2263 /* Prevent relocation handling by bfd for MIPS ELF64. */
2265 static void
2266 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2267 arelent *cache_ptr ATTRIBUTE_UNUSED,
2268 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2270 BFD_ASSERT (0);
2273 static void
2274 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2275 arelent *cache_ptr ATTRIBUTE_UNUSED,
2276 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2278 BFD_ASSERT (0);
2281 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2282 to three relocs, we must tell the user to allocate more space. */
2284 static long
2285 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
2287 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2290 static long
2291 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
2293 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2296 /* We must also copy more relocations than the corresponding functions
2297 in elf.c would, so the two following functions are slightly
2298 modified from elf.c, that multiply the external relocation count by
2299 3 to obtain the internal relocation count. */
2301 static long
2302 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2303 arelent **relptr, asymbol **symbols)
2305 arelent *tblptr;
2306 unsigned int i;
2307 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2309 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2310 return -1;
2312 tblptr = section->relocation;
2313 for (i = 0; i < section->reloc_count * 3; i++)
2314 *relptr++ = tblptr++;
2316 *relptr = NULL;
2318 return section->reloc_count * 3;
2321 static long
2322 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2323 asymbol **syms)
2325 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
2326 asection *s;
2327 long ret;
2329 if (elf_dynsymtab (abfd) == 0)
2331 bfd_set_error (bfd_error_invalid_operation);
2332 return -1;
2335 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2336 ret = 0;
2337 for (s = abfd->sections; s != NULL; s = s->next)
2339 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2340 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2341 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2343 arelent *p;
2344 long count, i;
2346 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2347 return -1;
2348 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2349 p = s->relocation;
2350 for (i = 0; i < count; i++)
2351 *storage++ = p++;
2352 ret += count;
2356 *storage = NULL;
2358 return ret;
2361 /* Read the relocations from one reloc section. This is mostly copied
2362 from elfcode.h, except for the changes to expand one external
2363 relocation to 3 internal ones. We must unfortunately set
2364 reloc_count to the number of external relocations, because a lot of
2365 generic code seems to depend on this. */
2367 static bfd_boolean
2368 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2369 Elf_Internal_Shdr *rel_hdr,
2370 bfd_size_type reloc_count,
2371 arelent *relents, asymbol **symbols,
2372 bfd_boolean dynamic)
2374 void *allocated;
2375 bfd_byte *native_relocs;
2376 arelent *relent;
2377 bfd_vma i;
2378 int entsize;
2379 bfd_boolean rela_p;
2381 allocated = bfd_malloc (rel_hdr->sh_size);
2382 if (allocated == NULL)
2383 return FALSE;
2385 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2386 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2387 != rel_hdr->sh_size))
2388 goto error_return;
2390 native_relocs = allocated;
2392 entsize = rel_hdr->sh_entsize;
2393 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2394 || entsize == sizeof (Elf64_Mips_External_Rela));
2396 if (entsize == sizeof (Elf64_Mips_External_Rel))
2397 rela_p = FALSE;
2398 else
2399 rela_p = TRUE;
2401 for (i = 0, relent = relents;
2402 i < reloc_count;
2403 i++, native_relocs += entsize)
2405 Elf64_Mips_Internal_Rela rela;
2406 bfd_boolean used_sym, used_ssym;
2407 int ir;
2409 if (entsize == sizeof (Elf64_Mips_External_Rela))
2410 mips_elf64_swap_reloca_in (abfd,
2411 (Elf64_Mips_External_Rela *) native_relocs,
2412 &rela);
2413 else
2414 mips_elf64_swap_reloc_in (abfd,
2415 (Elf64_Mips_External_Rel *) native_relocs,
2416 &rela);
2418 /* Each entry represents exactly three actual relocations. */
2420 used_sym = FALSE;
2421 used_ssym = FALSE;
2422 for (ir = 0; ir < 3; ir++)
2424 enum elf_mips_reloc_type type;
2426 switch (ir)
2428 default:
2429 abort ();
2430 case 0:
2431 type = (enum elf_mips_reloc_type) rela.r_type;
2432 break;
2433 case 1:
2434 type = (enum elf_mips_reloc_type) rela.r_type2;
2435 break;
2436 case 2:
2437 type = (enum elf_mips_reloc_type) rela.r_type3;
2438 break;
2441 /* Some types require symbols, whereas some do not. */
2442 switch (type)
2444 case R_MIPS_NONE:
2445 case R_MIPS_LITERAL:
2446 case R_MIPS_INSERT_A:
2447 case R_MIPS_INSERT_B:
2448 case R_MIPS_DELETE:
2449 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2450 break;
2452 default:
2453 if (! used_sym)
2455 if (rela.r_sym == 0)
2456 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2457 else
2459 asymbol **ps, *s;
2461 ps = symbols + rela.r_sym - 1;
2462 s = *ps;
2463 if ((s->flags & BSF_SECTION_SYM) == 0)
2464 relent->sym_ptr_ptr = ps;
2465 else
2466 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2469 used_sym = TRUE;
2471 else if (! used_ssym)
2473 switch (rela.r_ssym)
2475 case RSS_UNDEF:
2476 relent->sym_ptr_ptr =
2477 bfd_abs_section_ptr->symbol_ptr_ptr;
2478 break;
2480 case RSS_GP:
2481 case RSS_GP0:
2482 case RSS_LOC:
2483 /* FIXME: I think these need to be handled using
2484 special howto structures. */
2485 BFD_ASSERT (0);
2486 break;
2488 default:
2489 BFD_ASSERT (0);
2490 break;
2493 used_ssym = TRUE;
2495 else
2496 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2498 break;
2501 /* The address of an ELF reloc is section relative for an
2502 object file, and absolute for an executable file or
2503 shared library. The address of a BFD reloc is always
2504 section relative. */
2505 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2506 relent->address = rela.r_offset;
2507 else
2508 relent->address = rela.r_offset - asect->vma;
2510 relent->addend = rela.r_addend;
2512 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2514 ++relent;
2518 asect->reloc_count += (relent - relents) / 3;
2520 if (allocated != NULL)
2521 free (allocated);
2523 return TRUE;
2525 error_return:
2526 if (allocated != NULL)
2527 free (allocated);
2528 return FALSE;
2531 /* Read the relocations. On Irix 6, there can be two reloc sections
2532 associated with a single data section. This is copied from
2533 elfcode.h as well, with changes as small as accounting for 3
2534 internal relocs per external reloc and resetting reloc_count to
2535 zero before processing the relocs of a section. */
2537 static bfd_boolean
2538 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2539 asymbol **symbols, bfd_boolean dynamic)
2541 struct bfd_elf_section_data * const d = elf_section_data (asect);
2542 Elf_Internal_Shdr *rel_hdr;
2543 Elf_Internal_Shdr *rel_hdr2;
2544 bfd_size_type reloc_count;
2545 bfd_size_type reloc_count2;
2546 arelent *relents;
2547 bfd_size_type amt;
2549 if (asect->relocation != NULL)
2550 return TRUE;
2552 if (! dynamic)
2554 if ((asect->flags & SEC_RELOC) == 0
2555 || asect->reloc_count == 0)
2556 return TRUE;
2558 rel_hdr = &d->rel_hdr;
2559 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2560 rel_hdr2 = d->rel_hdr2;
2561 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2563 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2564 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2565 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2568 else
2570 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2571 case because relocations against this section may use the
2572 dynamic symbol table, and in that case bfd_section_from_shdr
2573 in elf.c does not update the RELOC_COUNT. */
2574 if (asect->size == 0)
2575 return TRUE;
2577 rel_hdr = &d->this_hdr;
2578 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2579 rel_hdr2 = NULL;
2580 reloc_count2 = 0;
2583 /* Allocate space for 3 arelent structures for each Rel structure. */
2584 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2585 relents = bfd_alloc (abfd, amt);
2586 if (relents == NULL)
2587 return FALSE;
2589 /* The slurp_one_reloc_table routine increments reloc_count. */
2590 asect->reloc_count = 0;
2592 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2593 rel_hdr, reloc_count,
2594 relents,
2595 symbols, dynamic))
2596 return FALSE;
2597 if (d->rel_hdr2 != NULL)
2599 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2600 rel_hdr2, reloc_count2,
2601 relents + reloc_count * 3,
2602 symbols, dynamic))
2603 return FALSE;
2606 asect->relocation = relents;
2607 return TRUE;
2610 /* Write out the relocations. */
2612 static void
2613 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2615 bfd_boolean *failedp = data;
2616 int count;
2617 Elf_Internal_Shdr *rel_hdr;
2618 unsigned int idx;
2620 /* If we have already failed, don't do anything. */
2621 if (*failedp)
2622 return;
2624 if ((sec->flags & SEC_RELOC) == 0)
2625 return;
2627 /* The linker backend writes the relocs out itself, and sets the
2628 reloc_count field to zero to inhibit writing them here. Also,
2629 sometimes the SEC_RELOC flag gets set even when there aren't any
2630 relocs. */
2631 if (sec->reloc_count == 0)
2632 return;
2634 /* We can combine up to three relocs that refer to the same address
2635 if the latter relocs have no associated symbol. */
2636 count = 0;
2637 for (idx = 0; idx < sec->reloc_count; idx++)
2639 bfd_vma addr;
2640 unsigned int i;
2642 ++count;
2644 addr = sec->orelocation[idx]->address;
2645 for (i = 0; i < 2; i++)
2647 arelent *r;
2649 if (idx + 1 >= sec->reloc_count)
2650 break;
2651 r = sec->orelocation[idx + 1];
2652 if (r->address != addr
2653 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2654 || (*r->sym_ptr_ptr)->value != 0)
2655 break;
2657 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2659 ++idx;
2663 rel_hdr = &elf_section_data (sec)->rel_hdr;
2665 /* Do the actual relocation. */
2667 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2668 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2669 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2670 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2671 else
2672 BFD_ASSERT (0);
2675 static void
2676 mips_elf64_write_rel (bfd *abfd, asection *sec,
2677 Elf_Internal_Shdr *rel_hdr,
2678 int *count, void *data)
2680 bfd_boolean *failedp = data;
2681 Elf64_Mips_External_Rel *ext_rel;
2682 unsigned int idx;
2683 asymbol *last_sym = 0;
2684 int last_sym_idx = 0;
2686 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2687 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2688 if (rel_hdr->contents == NULL)
2690 *failedp = TRUE;
2691 return;
2694 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2695 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2697 arelent *ptr;
2698 Elf64_Mips_Internal_Rela int_rel;
2699 asymbol *sym;
2700 int n;
2701 unsigned int i;
2703 ptr = sec->orelocation[idx];
2705 /* The address of an ELF reloc is section relative for an object
2706 file, and absolute for an executable file or shared library.
2707 The address of a BFD reloc is always section relative. */
2708 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2709 int_rel.r_offset = ptr->address;
2710 else
2711 int_rel.r_offset = ptr->address + sec->vma;
2713 sym = *ptr->sym_ptr_ptr;
2714 if (sym == last_sym)
2715 n = last_sym_idx;
2716 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2717 n = STN_UNDEF;
2718 else
2720 last_sym = sym;
2721 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2722 if (n < 0)
2724 *failedp = TRUE;
2725 return;
2727 last_sym_idx = n;
2730 int_rel.r_sym = n;
2731 int_rel.r_ssym = RSS_UNDEF;
2733 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2734 && ! _bfd_elf_validate_reloc (abfd, ptr))
2736 *failedp = TRUE;
2737 return;
2740 int_rel.r_type = ptr->howto->type;
2741 int_rel.r_type2 = (int) R_MIPS_NONE;
2742 int_rel.r_type3 = (int) R_MIPS_NONE;
2744 for (i = 0; i < 2; i++)
2746 arelent *r;
2748 if (idx + 1 >= sec->reloc_count)
2749 break;
2750 r = sec->orelocation[idx + 1];
2751 if (r->address != ptr->address
2752 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2753 || (*r->sym_ptr_ptr)->value != 0)
2754 break;
2756 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2758 if (i == 0)
2759 int_rel.r_type2 = r->howto->type;
2760 else
2761 int_rel.r_type3 = r->howto->type;
2763 ++idx;
2766 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2769 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2770 == *count);
2773 static void
2774 mips_elf64_write_rela (bfd *abfd, asection *sec,
2775 Elf_Internal_Shdr *rela_hdr,
2776 int *count, void *data)
2778 bfd_boolean *failedp = data;
2779 Elf64_Mips_External_Rela *ext_rela;
2780 unsigned int idx;
2781 asymbol *last_sym = 0;
2782 int last_sym_idx = 0;
2784 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2785 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2786 if (rela_hdr->contents == NULL)
2788 *failedp = TRUE;
2789 return;
2792 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2793 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2795 arelent *ptr;
2796 Elf64_Mips_Internal_Rela int_rela;
2797 asymbol *sym;
2798 int n;
2799 unsigned int i;
2801 ptr = sec->orelocation[idx];
2803 /* The address of an ELF reloc is section relative for an object
2804 file, and absolute for an executable file or shared library.
2805 The address of a BFD reloc is always section relative. */
2806 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2807 int_rela.r_offset = ptr->address;
2808 else
2809 int_rela.r_offset = ptr->address + sec->vma;
2811 sym = *ptr->sym_ptr_ptr;
2812 if (sym == last_sym)
2813 n = last_sym_idx;
2814 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2815 n = STN_UNDEF;
2816 else
2818 last_sym = sym;
2819 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2820 if (n < 0)
2822 *failedp = TRUE;
2823 return;
2825 last_sym_idx = n;
2828 int_rela.r_sym = n;
2829 int_rela.r_addend = ptr->addend;
2830 int_rela.r_ssym = RSS_UNDEF;
2832 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2833 && ! _bfd_elf_validate_reloc (abfd, ptr))
2835 *failedp = TRUE;
2836 return;
2839 int_rela.r_type = ptr->howto->type;
2840 int_rela.r_type2 = (int) R_MIPS_NONE;
2841 int_rela.r_type3 = (int) R_MIPS_NONE;
2843 for (i = 0; i < 2; i++)
2845 arelent *r;
2847 if (idx + 1 >= sec->reloc_count)
2848 break;
2849 r = sec->orelocation[idx + 1];
2850 if (r->address != ptr->address
2851 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2852 || (*r->sym_ptr_ptr)->value != 0)
2853 break;
2855 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2857 if (i == 0)
2858 int_rela.r_type2 = r->howto->type;
2859 else
2860 int_rela.r_type3 = r->howto->type;
2862 ++idx;
2865 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2868 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2869 == *count);
2872 /* Set the right machine number for a MIPS ELF file. */
2874 static bfd_boolean
2875 mips_elf64_object_p (bfd *abfd)
2877 unsigned long mach;
2879 /* Irix 6 is broken. Object file symbol tables are not always
2880 sorted correctly such that local symbols precede global symbols,
2881 and the sh_info field in the symbol table is not always right. */
2882 if (elf64_mips_irix_compat (abfd) != ict_none)
2883 elf_bad_symtab (abfd) = TRUE;
2885 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2886 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2887 return TRUE;
2890 /* Depending on the target vector we generate some version of Irix
2891 executables or "normal" MIPS ELF ABI executables. */
2892 static irix_compat_t
2893 elf64_mips_irix_compat (bfd *abfd)
2895 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2896 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2897 return ict_irix6;
2898 else
2899 return ict_none;
2902 /* Support for core dump NOTE sections. */
2903 static bfd_boolean
2904 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2906 int offset;
2907 unsigned int size;
2909 switch (note->descsz)
2911 default:
2912 return FALSE;
2914 case 480: /* Linux/MIPS - N64 kernel */
2915 /* pr_cursig */
2916 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2918 /* pr_pid */
2919 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2921 /* pr_reg */
2922 offset = 112;
2923 size = 360;
2925 break;
2928 /* Make a ".reg/999" section. */
2929 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2930 size, note->descpos + offset);
2933 static bfd_boolean
2934 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2936 switch (note->descsz)
2938 default:
2939 return FALSE;
2941 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2942 elf_tdata (abfd)->core_program
2943 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2944 elf_tdata (abfd)->core_command
2945 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2948 /* Note that for some reason, a spurious space is tacked
2949 onto the end of the args in some (at least one anyway)
2950 implementations, so strip it off if it exists. */
2953 char *command = elf_tdata (abfd)->core_command;
2954 int n = strlen (command);
2956 if (0 < n && command[n - 1] == ' ')
2957 command[n - 1] = '\0';
2960 return TRUE;
2963 /* ECOFF swapping routines. These are used when dealing with the
2964 .mdebug section, which is in the ECOFF debugging format. */
2965 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2967 /* Symbol table magic number. */
2968 magicSym2,
2969 /* Alignment of debugging information. E.g., 4. */
2971 /* Sizes of external symbolic information. */
2972 sizeof (struct hdr_ext),
2973 sizeof (struct dnr_ext),
2974 sizeof (struct pdr_ext),
2975 sizeof (struct sym_ext),
2976 sizeof (struct opt_ext),
2977 sizeof (struct fdr_ext),
2978 sizeof (struct rfd_ext),
2979 sizeof (struct ext_ext),
2980 /* Functions to swap in external symbolic data. */
2981 ecoff_swap_hdr_in,
2982 ecoff_swap_dnr_in,
2983 ecoff_swap_pdr_in,
2984 ecoff_swap_sym_in,
2985 ecoff_swap_opt_in,
2986 ecoff_swap_fdr_in,
2987 ecoff_swap_rfd_in,
2988 ecoff_swap_ext_in,
2989 _bfd_ecoff_swap_tir_in,
2990 _bfd_ecoff_swap_rndx_in,
2991 /* Functions to swap out external symbolic data. */
2992 ecoff_swap_hdr_out,
2993 ecoff_swap_dnr_out,
2994 ecoff_swap_pdr_out,
2995 ecoff_swap_sym_out,
2996 ecoff_swap_opt_out,
2997 ecoff_swap_fdr_out,
2998 ecoff_swap_rfd_out,
2999 ecoff_swap_ext_out,
3000 _bfd_ecoff_swap_tir_out,
3001 _bfd_ecoff_swap_rndx_out,
3002 /* Function to read in symbolic data. */
3003 _bfd_mips_elf_read_ecoff_info
3006 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3007 standard ELF. This structure is used to redirect the relocation
3008 handling routines. */
3010 const struct elf_size_info mips_elf64_size_info =
3012 sizeof (Elf64_External_Ehdr),
3013 sizeof (Elf64_External_Phdr),
3014 sizeof (Elf64_External_Shdr),
3015 sizeof (Elf64_Mips_External_Rel),
3016 sizeof (Elf64_Mips_External_Rela),
3017 sizeof (Elf64_External_Sym),
3018 sizeof (Elf64_External_Dyn),
3019 sizeof (Elf_External_Note),
3020 4, /* hash-table entry size */
3021 3, /* internal relocations per external relocations */
3022 64, /* arch_size */
3023 3, /* log_file_align */
3024 ELFCLASS64,
3025 EV_CURRENT,
3026 bfd_elf64_write_out_phdrs,
3027 bfd_elf64_write_shdrs_and_ehdr,
3028 mips_elf64_write_relocs,
3029 bfd_elf64_swap_symbol_in,
3030 bfd_elf64_swap_symbol_out,
3031 mips_elf64_slurp_reloc_table,
3032 bfd_elf64_slurp_symbol_table,
3033 bfd_elf64_swap_dyn_in,
3034 bfd_elf64_swap_dyn_out,
3035 mips_elf64_be_swap_reloc_in,
3036 mips_elf64_be_swap_reloc_out,
3037 mips_elf64_be_swap_reloca_in,
3038 mips_elf64_be_swap_reloca_out
3041 #define ELF_ARCH bfd_arch_mips
3042 #define ELF_MACHINE_CODE EM_MIPS
3044 #define elf_backend_collect TRUE
3045 #define elf_backend_type_change_ok TRUE
3046 #define elf_backend_can_gc_sections TRUE
3047 #define elf_info_to_howto mips_elf64_info_to_howto_rela
3048 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
3049 #define elf_backend_object_p mips_elf64_object_p
3050 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3051 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3052 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3053 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3054 #define elf_backend_section_from_bfd_section \
3055 _bfd_mips_elf_section_from_bfd_section
3056 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3057 #define elf_backend_link_output_symbol_hook \
3058 _bfd_mips_elf_link_output_symbol_hook
3059 #define elf_backend_create_dynamic_sections \
3060 _bfd_mips_elf_create_dynamic_sections
3061 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3062 #define elf_backend_adjust_dynamic_symbol \
3063 _bfd_mips_elf_adjust_dynamic_symbol
3064 #define elf_backend_always_size_sections \
3065 _bfd_mips_elf_always_size_sections
3066 #define elf_backend_size_dynamic_sections \
3067 _bfd_mips_elf_size_dynamic_sections
3068 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3069 #define elf_backend_finish_dynamic_symbol \
3070 _bfd_mips_elf_finish_dynamic_symbol
3071 #define elf_backend_finish_dynamic_sections \
3072 _bfd_mips_elf_finish_dynamic_sections
3073 #define elf_backend_final_write_processing \
3074 _bfd_mips_elf_final_write_processing
3075 #define elf_backend_additional_program_headers \
3076 _bfd_mips_elf_additional_program_headers
3077 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3078 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3079 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3080 #define elf_backend_copy_indirect_symbol \
3081 _bfd_mips_elf_copy_indirect_symbol
3082 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
3083 #define elf_backend_ignore_discarded_relocs \
3084 _bfd_mips_elf_ignore_discarded_relocs
3085 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
3086 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3087 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3088 #define elf_backend_size_info mips_elf64_size_info
3090 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3091 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
3093 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3095 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3096 work better/work only in RELA, so we default to this. */
3097 #define elf_backend_may_use_rel_p 1
3098 #define elf_backend_may_use_rela_p 1
3099 #define elf_backend_default_use_rela_p 1
3101 #define elf_backend_write_section _bfd_mips_elf_write_section
3103 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3104 MIPS-specific function only applies to IRIX5, which had no 64-bit
3105 ABI. */
3106 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
3107 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
3108 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
3109 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
3110 #define bfd_elf64_bfd_get_relocated_section_contents \
3111 _bfd_elf_mips_get_relocated_section_contents
3112 #define bfd_elf64_bfd_link_hash_table_create \
3113 _bfd_mips_elf_link_hash_table_create
3114 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
3115 #define bfd_elf64_bfd_merge_private_bfd_data \
3116 _bfd_mips_elf_merge_private_bfd_data
3117 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3118 #define bfd_elf64_bfd_print_private_bfd_data \
3119 _bfd_mips_elf_print_private_bfd_data
3121 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3122 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3123 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3124 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3125 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
3127 /* MIPS ELF64 archive functions. */
3128 #define bfd_elf64_archive_functions
3129 extern bfd_boolean bfd_elf64_archive_slurp_armap
3130 (bfd *);
3131 extern bfd_boolean bfd_elf64_archive_write_armap
3132 (bfd *, unsigned int, struct orl *, unsigned int, int);
3133 #define bfd_elf64_archive_slurp_extended_name_table \
3134 _bfd_archive_coff_slurp_extended_name_table
3135 #define bfd_elf64_archive_construct_extended_name_table \
3136 _bfd_archive_coff_construct_extended_name_table
3137 #define bfd_elf64_archive_truncate_arname \
3138 _bfd_archive_coff_truncate_arname
3139 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3140 #define bfd_elf64_archive_openr_next_archived_file \
3141 _bfd_archive_coff_openr_next_archived_file
3142 #define bfd_elf64_archive_get_elt_at_index \
3143 _bfd_archive_coff_get_elt_at_index
3144 #define bfd_elf64_archive_generic_stat_arch_elt \
3145 _bfd_archive_coff_generic_stat_arch_elt
3146 #define bfd_elf64_archive_update_armap_timestamp \
3147 _bfd_archive_coff_update_armap_timestamp
3149 /* The SGI style (n)64 NewABI. */
3150 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3151 #define TARGET_LITTLE_NAME "elf64-littlemips"
3152 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3153 #define TARGET_BIG_NAME "elf64-bigmips"
3155 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
3156 a value of 0x1000, and we are compatible.
3157 FIXME: How does this affect NewABI? */
3158 #define ELF_MAXPAGESIZE 0x1000
3160 #include "elf64-target.h"
3162 /* The SYSV-style 'traditional' (n)64 NewABI. */
3163 #undef TARGET_LITTLE_SYM
3164 #undef TARGET_LITTLE_NAME
3165 #undef TARGET_BIG_SYM
3166 #undef TARGET_BIG_NAME
3168 #undef ELF_MAXPAGESIZE
3170 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3171 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3172 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3173 #define TARGET_BIG_NAME "elf64-tradbigmips"
3175 /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
3176 page sizes of up to that limit, so we need to respect it. */
3177 #define ELF_MAXPAGESIZE 0x10000
3178 #define elf64_bed elf64_tradbed
3180 /* Include the target file again for this target. */
3181 #include "elf64-target.h"